(function () {
	var t = {
			9285: function (t, e, i) {
				i(7658), i(541);
				/*! Fabric.js Copyright 2008-2015, Printio (Juriy Zaytsev, Maxim Chernyak) */ var n = n || { version: '5.2.1' };
				if (
					((e.fabric = n),
					'undefined' !== typeof document &&
						'undefined' !== typeof window &&
						(document instanceof ('undefined' !== typeof HTMLDocument ? HTMLDocument : Document) ? (n.document = document) : (n.document = document.implementation.createHTMLDocument('')),
						(n.window = window)),
					(n.isTouchSupported = 'ontouchstart' in n.window || 'ontouchstart' in n.document || (n.window && n.window.navigator && n.window.navigator.maxTouchPoints > 0)),
					(n.isLikelyNode = 'undefined' !== typeof Buffer && 'undefined' === typeof window),
					(n.SHARED_ATTRIBUTES = [
						'display',
						'transform',
						'fill',
						'fill-opacity',
						'fill-rule',
						'opacity',
						'stroke',
						'stroke-dasharray',
						'stroke-linecap',
						'stroke-dashoffset',
						'stroke-linejoin',
						'stroke-miterlimit',
						'stroke-opacity',
						'stroke-width',
						'id',
						'paint-order',
						'vector-effect',
						'instantiated_by_use',
						'clip-path'
					]),
					(n.DPI = 96),
					(n.reNum = '(?:[-+]?(?:\\d+|\\d*\\.\\d+)(?:[eE][-+]?\\d+)?)'),
					(n.commaWsp = '(?:\\s+,?\\s*|,\\s*)'),
					(n.rePathCommand = /([-+]?((\d+\.\d+)|((\d+)|(\.\d+)))(?:[eE][-+]?\d+)?)/gi),
					(n.reNonWord = /[ \n\.,;!\?\-]/),
					(n.fontPaths = {}),
					(n.iMatrix = [1, 0, 0, 1, 0, 0]),
					(n.svgNS = 'http://www.w3.org/2000/svg'),
					(n.perfLimitSizeTotal = 2097152),
					(n.maxCacheSideLimit = 4096),
					(n.minCacheSideLimit = 256),
					(n.charWidthsCache = {}),
					(n.textureSize = 2048),
					(n.disableStyleCopyPaste = !1),
					(n.enableGLFiltering = !0),
					(n.devicePixelRatio = n.window.devicePixelRatio || n.window.webkitDevicePixelRatio || n.window.mozDevicePixelRatio || 1),
					(n.browserShadowBlurConstant = 1),
					(n.arcToSegmentsCache = {}),
					(n.boundsOfCurveCache = {}),
					(n.cachesBoundsOfCurve = !0),
					(n.forceGLPutImageData = !1),
					(n.initFilterBackend = function () {
						return n.enableGLFiltering && n.isWebglSupported && n.isWebglSupported(n.textureSize)
							? (console.log('max texture size: ' + n.maxTextureSize), new n.WebglFilterBackend({ tileSize: n.textureSize }))
							: n.Canvas2dFilterBackend
							? new n.Canvas2dFilterBackend()
							: void 0;
					}),
					'undefined' !== typeof document && 'undefined' !== typeof window && (window.fabric = n),
					'undefined' === typeof r)
				)
					var r = {};
				if (
					((function (t) {
						'use strict';
						(t.modifyEventListener = !1),
							(t.modifySelectors = !1),
							(t.configure = function (e) {
								isFinite(e.modifyEventListener) && (t.modifyEventListener = e.modifyEventListener),
									isFinite(e.modifySelectors) && (t.modifySelectors = e.modifySelectors),
									!1 === p && t.modifyEventListener && g(),
									!1 === v && t.modifySelectors && m();
							}),
							(t.add = function (t, e, n, r) {
								return i(t, e, n, r, 'add');
							}),
							(t.remove = function (t, e, n, r) {
								return i(t, e, n, r, 'remove');
							}),
							(t.returnFalse = function (t) {
								return !1;
							}),
							(t.stop = function (t) {
								t && (t.stopPropagation && t.stopPropagation(), (t.cancelBubble = !0), (t.cancelBubbleCount = 0));
							}),
							(t.prevent = function (t) {
								t && (t.preventDefault ? t.preventDefault() : t.preventManipulation ? t.preventManipulation() : (t.returnValue = !1));
							}),
							(t.cancel = function (e) {
								t.stop(e), t.prevent(e);
							}),
							(t.blur = function () {
								var t = document.activeElement;
								if (t) {
									var e = document.activeElement.nodeName;
									('INPUT' !== e && 'TEXTAREA' !== e && 'true' !== t.contentEditable) || (t.blur && t.blur());
								}
							}),
							(t.getEventSupport = function (t, e) {
								if (('string' === typeof t && ((e = t), (t = window)), (e = 'on' + e), e in t)) return !0;
								if ((t.setAttribute || (t = document.createElement('div')), t.setAttribute && t.removeAttribute)) {
									t.setAttribute(e, '');
									var i = 'function' === typeof t[e];
									return 'undefined' !== typeof t[e] && (t[e] = null), t.removeAttribute(e), i;
								}
							});
						var e = function (t) {
								if (!t || 'object' !== typeof t) return t;
								var i = new t.constructor();
								for (var n in t) t[n] && 'object' === typeof t[n] ? (i[n] = e(t[n])) : (i[n] = t[n]);
								return i;
							},
							i = function (s, a, l, p, g, v) {
								if (((p = p || {}), '[object Object]' === String(s))) {
									var m = s;
									if (((s = m.target), delete m.target, !m.type || !m.listener)) {
										for (var y in m) {
											var b = m[y];
											'function' !== typeof b && (p[y] = b);
										}
										var x = {};
										for (var _ in m) {
											y = _.split(',');
											var w = m[_],
												C = {};
											for (var S in p) C[S] = p[S];
											if ('function' === typeof w) l = w;
											else {
												if ('function' !== typeof w.listener) continue;
												l = w.listener;
												for (var S in w) 'function' !== typeof w[S] && (C[S] = w[S]);
											}
											for (var T = 0; T < y.length; T++) x[_] = r.add(s, y[T], l, C, g);
										}
										return x;
									}
									for (var _ in ((a = m.type), delete m.type, (l = m.listener), delete m.listener, m)) p[_] = m[_];
								}
								if (s && a && l) {
									if ('string' === typeof s && 'ready' === a) {
										if (!window.eventjs_stallOnReady) {
											var O = new Date().getTime(),
												k = p.timeout,
												P = p.interval || 1e3 / 60,
												E = window.setInterval(function () {
													new Date().getTime() - O > k && window.clearInterval(E), document.querySelector(s) && (window.clearInterval(E), setTimeout(l, 1));
												}, P);
											return;
										}
										(a = 'load'), (s = window);
									}
									if ('string' === typeof s) {
										if (((s = document.querySelectorAll(s)), 0 === s.length)) return o('Missing target on listener!', arguments);
										1 === s.length && (s = s[0]);
									}
									var M,
										j = {};
									if (s.length > 0 && s !== window) {
										for (var D = 0, A = s.length; D < A; D++) (M = i(s[D], a, l, e(p), g)), M && (j[D] = M);
										return n(j);
									}
									if (
										('string' === typeof a && ((a = a.toLowerCase()), -1 !== a.indexOf(' ') ? (a = a.split(' ')) : -1 !== a.indexOf(',') && (a = a.split(','))),
										'string' !== typeof a)
									) {
										if ('number' === typeof a.length) for (var F = 0, L = a.length; F < L; F++) (M = i(s, a[F], l, e(p), g)), M && (j[a[F]] = M);
										else for (var _ in a) (M = 'function' === typeof a[_] ? i(s, _, a[_], e(p), g) : i(s, _, a[_].listener, e(a[_]), g)), M && (j[_] = M);
										return n(j);
									}
									if ((0 === a.indexOf('on') && (a = a.slice(2)), 'object' !== typeof s)) return o('Target is not defined!', arguments);
									if ('function' !== typeof l) return o('Listener is not a function!', arguments);
									var I = p.useCapture || !1,
										R = u(s) + '.' + u(l) + '.' + (I ? 1 : 0);
									if (t.Gesture && t.Gesture._gestureHandlers[a]) {
										if (((R = a + R), 'remove' === g)) {
											if (!h[R]) return;
											h[R].remove(), delete h[R];
										} else if ('add' === g) {
											if (h[R]) return h[R].add(), h[R];
											if (p.useCall && !t.modifyEventListener) {
												var B = l;
												l = function (t, e) {
													for (var i in e) t[i] = e[i];
													return B.call(s, t);
												};
											}
											(p.gesture = a), (p.target = s), (p.listener = l), (p.fromOverwrite = v), (h[R] = t.proxy[a](p));
										}
										return h[R];
									}
									var z,
										X = c(a);
									for (T = 0; T < X.length; T++)
										if (((a = X[T]), (z = a + '.' + R), 'remove' === g)) {
											if (!h[z]) continue;
											s[d](a, l, I), delete h[z];
										} else if ('add' === g) {
											if (h[z]) return h[z];
											s[f](a, l, I),
												(h[z] = {
													id: z,
													type: a,
													target: s,
													listener: l,
													remove: function () {
														for (var e = 0; e < X.length; e++) t.remove(s, X[e], l, p);
													}
												});
										}
									return h[z];
								}
							},
							n = function (t) {
								return {
									remove: function () {
										for (var e in t) t[e].remove();
									},
									add: function () {
										for (var e in t) t[e].add();
									}
								};
							},
							o = function (t, e) {
								'undefined' !== typeof console && 'undefined' !== typeof console.error && console.error(t, e);
							},
							s = { msPointer: ['MSPointerDown', 'MSPointerMove', 'MSPointerUp'], touch: ['touchstart', 'touchmove', 'touchend'], mouse: ['mousedown', 'mousemove', 'mouseup'] },
							a = { MSPointerDown: 0, MSPointerMove: 1, MSPointerUp: 2, touchstart: 0, touchmove: 1, touchend: 2, mousedown: 0, mousemove: 1, mouseup: 2 },
							c =
								((function () {
									(t.supports = {}),
										window.navigator.msPointerEnabled && (t.supports.msPointer = !0),
										t.getEventSupport('touchstart') && (t.supports.touch = !0),
										t.getEventSupport('mousedown') && (t.supports.mouse = !0);
								})(),
								(function () {
									return function (e) {
										var i = document.addEventListener ? '' : 'on',
											n = a[e];
										if (isFinite(n)) {
											var r = [];
											for (var o in t.supports) r.push(i + s[o][n]);
											return r;
										}
										return [i + e];
									};
								})()),
							h = {},
							l = 0,
							u = function (t) {
								return t === window ? '#window' : t === document ? '#document' : (t.uniqueID || (t.uniqueID = 'e' + l++), t.uniqueID);
							},
							f = document.addEventListener ? 'addEventListener' : 'attachEvent',
							d = document.removeEventListener ? 'removeEventListener' : 'detachEvent';
						t.createPointerEvent = function (e, i, n) {
							var r = i.gesture,
								o = i.target,
								s = e.changedTouches || t.proxy.getCoords(e);
							if (s.length) {
								var a = s[0];
								(i.pointers = n ? [] : s), (i.pageX = a.pageX), (i.pageY = a.pageY), (i.x = i.pageX), (i.y = i.pageY);
							}
							var c = document.createEvent('Event');
							for (var h in (c.initEvent(r, !0, !0), (c.originalEvent = e), i)) 'target' !== h && (c[h] = i[h]);
							var l = c.type;
							t.Gesture && t.Gesture._gestureHandlers[l] && i.oldListener.call(o, c, i, !1);
						};
						var p = !1,
							g = function () {
								if (window.HTMLElement) {
									var e = function (e) {
										var n = function (n) {
											var r = n + 'EventListener',
												o = e[r];
											e[r] = function (e, r, s) {
												if (t.Gesture && t.Gesture._gestureHandlers[e]) {
													var a = s;
													'object' === typeof s ? (a.useCall = !0) : (a = { useCall: !0, useCapture: s }), i(this, e, r, a, n, !0);
												} else for (var h = c(e), l = 0; l < h.length; l++) o.call(this, h[l], r, s);
											};
										};
										n('add'), n('remove');
									};
									navigator.userAgent.match(/Firefox/) ? (e(HTMLDivElement.prototype), e(HTMLCanvasElement.prototype)) : e(HTMLElement.prototype), e(document), e(window);
								}
							},
							v = !1,
							m = function () {
								var t = NodeList.prototype;
								(t.removeEventListener = function (t, e, i) {
									for (var n = 0, r = this.length; n < r; n++) this[n].removeEventListener(t, e, i);
								}),
									(t.addEventListener = function (t, e, i) {
										for (var n = 0, r = this.length; n < r; n++) this[n].addEventListener(t, e, i);
									});
							};
					})(r),
					'undefined' === typeof r)
				)
					r = {};
				if (
					('undefined' === typeof r.proxy && (r.proxy = {}),
					(r.proxy = (function (t) {
						'use strict';
						t.pointerSetup = function (t, e) {
							(t.target = t.target || window),
								(t.doc = t.target.ownerDocument || t.target),
								(t.minFingers = t.minFingers || t.fingers || 1),
								(t.maxFingers = t.maxFingers || t.fingers || 1 / 0),
								(t.position = t.position || 'relative'),
								delete t.fingers,
								(e = e || {}),
								(e.enabled = !0),
								(e.gesture = t.gesture),
								(e.target = t.target),
								(e.env = t.env),
								r.modifyEventListener && t.fromOverwrite && ((t.oldListener = t.listener), (t.listener = r.createPointerEvent));
							var i = 0,
								n = 0 === e.gesture.indexOf('pointer') && r.modifyEventListener ? 'pointer' : 'mouse';
							return (
								t.oldListener && (e.oldListener = t.oldListener),
								(e.listener = t.listener),
								(e.proxy = function (i) {
									(e.defaultListener = t.listener), (t.listener = i), i(t.event, e);
								}),
								(e.add = function () {
									!0 !== e.enabled &&
										(t.onPointerDown && r.add(t.target, n + 'down', t.onPointerDown),
										t.onPointerMove && r.add(t.doc, n + 'move', t.onPointerMove),
										t.onPointerUp && r.add(t.doc, n + 'up', t.onPointerUp),
										(e.enabled = !0));
								}),
								(e.remove = function () {
									!1 !== e.enabled &&
										(t.onPointerDown && r.remove(t.target, n + 'down', t.onPointerDown),
										t.onPointerMove && r.remove(t.doc, n + 'move', t.onPointerMove),
										t.onPointerUp && r.remove(t.doc, n + 'up', t.onPointerUp),
										e.reset(),
										(e.enabled = !1));
								}),
								(e.pause = function (e) {
									!t.onPointerMove || (e && !e.move) || r.remove(t.doc, n + 'move', t.onPointerMove),
										!t.onPointerUp || (e && !e.up) || r.remove(t.doc, n + 'up', t.onPointerUp),
										(i = t.fingers),
										(t.fingers = 0);
								}),
								(e.resume = function (e) {
									!t.onPointerMove || (e && !e.move) || r.add(t.doc, n + 'move', t.onPointerMove),
										!t.onPointerUp || (e && !e.up) || r.add(t.doc, n + 'up', t.onPointerUp),
										(t.fingers = i);
								}),
								(e.reset = function () {
									(t.tracker = {}), (t.fingers = 0);
								}),
								e
							);
						};
						var e = r.supports;
						(r.isMouse = !!e.mouse),
							(r.isMSPointer = !!e.touch),
							(r.isTouch = !!e.msPointer),
							(t.pointerStart = function (e, i, n) {
								var o = (e.type || 'mousedown').toUpperCase();
								0 === o.indexOf('MOUSE')
									? ((r.isMouse = !0), (r.isTouch = !1), (r.isMSPointer = !1))
									: 0 === o.indexOf('TOUCH')
									? ((r.isMouse = !1), (r.isTouch = !0), (r.isMSPointer = !1))
									: 0 === o.indexOf('MSPOINTER') && ((r.isMouse = !1), (r.isTouch = !1), (r.isMSPointer = !0));
								var s = function (t, e) {
									var i = n.bbox,
										r = (c[e] = {});
									switch (n.position) {
										case 'absolute':
											(r.offsetX = 0), (r.offsetY = 0);
											break;
										case 'differenceFromLast':
											(r.offsetX = t.pageX), (r.offsetY = t.pageY);
											break;
										case 'difference':
											(r.offsetX = t.pageX), (r.offsetY = t.pageY);
											break;
										case 'move':
											(r.offsetX = t.pageX - i.x1), (r.offsetY = t.pageY - i.y1);
											break;
										default:
											(r.offsetX = i.x1 - i.scrollLeft), (r.offsetY = i.y1 - i.scrollTop);
											break;
									}
									var o = t.pageX - r.offsetX,
										s = t.pageY - r.offsetY;
									(r.rotation = 0), (r.scale = 1), (r.startTime = r.moveTime = new Date().getTime()), (r.move = { x: o, y: s }), (r.start = { x: o, y: s }), n.fingers++;
								};
								(n.event = e), i.defaultListener && ((n.listener = i.defaultListener), delete i.defaultListener);
								for (var a = !n.fingers, c = n.tracker, h = e.changedTouches || t.getCoords(e), l = h.length, u = 0; u < l; u++) {
									var f = h[u],
										d = f.identifier || 1 / 0;
									if (n.fingers) {
										if (n.fingers >= n.maxFingers) {
											var p = [];
											for (var d in n.tracker) p.push(d);
											return (i.identifier = p.join(',')), a;
										}
										for (var g in c) {
											if (c[g].up) {
												delete c[g], s(f, d), (n.cancel = !0);
												break;
											}
											0;
										}
										if (c[d]) continue;
										s(f, d);
									} else (c = n.tracker = {}), (i.bbox = n.bbox = t.getBoundingBox(n.target)), (n.fingers = 0), (n.cancel = !1), s(f, d);
								}
								p = [];
								for (var d in n.tracker) p.push(d);
								return (i.identifier = p.join(',')), a;
							}),
							(t.pointerEnd = function (t, e, i, n) {
								for (var r = t.touches || [], o = r.length, s = {}, a = 0; a < o; a++) {
									var c = r[a],
										h = c.identifier;
									s[h || 1 / 0] = !0;
								}
								for (var h in i.tracker) {
									var l = i.tracker[h];
									s[h] ||
										l.up ||
										(n && n({ pageX: l.pageX, pageY: l.pageY, changedTouches: [{ pageX: l.pageX, pageY: l.pageY, identifier: 'Infinity' === h ? 1 / 0 : h }] }, 'up'),
										(l.up = !0),
										i.fingers--);
								}
								if (0 !== i.fingers) return !1;
								var u = [];
								for (var h in ((i.gestureFingers = 0), i.tracker)) i.gestureFingers++, u.push(h);
								return (e.identifier = u.join(',')), !0;
							}),
							(t.getCoords = function (e) {
								return (
									'undefined' !== typeof e.pageX
										? (t.getCoords = function (t) {
												return Array({ type: 'mouse', x: t.pageX, y: t.pageY, pageX: t.pageX, pageY: t.pageY, identifier: t.pointerId || 1 / 0 });
										  })
										: (t.getCoords = function (t) {
												var e = document.documentElement;
												return (
													(t = t || window.event),
													Array({
														type: 'mouse',
														x: t.clientX + e.scrollLeft,
														y: t.clientY + e.scrollTop,
														pageX: t.clientX + e.scrollLeft,
														pageY: t.clientY + e.scrollTop,
														identifier: 1 / 0
													})
												);
										  }),
									t.getCoords(e)
								);
							}),
							(t.getCoord = function (e) {
								if ('ontouchstart' in window) {
									var i = 0,
										n = 0;
									t.getCoord = function (t) {
										var e = t.changedTouches;
										return e && e.length ? { x: (i = e[0].pageX), y: (n = e[0].pageY) } : { x: i, y: n };
									};
								} else
									'undefined' !== typeof e.pageX && 'undefined' !== typeof e.pageY
										? (t.getCoord = function (t) {
												return { x: t.pageX, y: t.pageY };
										  })
										: (t.getCoord = function (t) {
												var e = document.documentElement;
												return (t = t || window.event), { x: t.clientX + e.scrollLeft, y: t.clientY + e.scrollTop };
										  });
								return t.getCoord(e);
							});
						var i = function (t, e) {
							var i = parseFloat(t.getPropertyValue(e), 10);
							return isFinite(i) ? i : 0;
						};
						return (
							(t.getBoundingBox = function (t) {
								(t !== window && t !== document) || (t = document.body);
								var e = {},
									n = t.getBoundingClientRect();
								(e.width = n.width),
									(e.height = n.height),
									(e.x1 = n.left),
									(e.y1 = n.top),
									(e.scaleX = n.width / t.offsetWidth || 1),
									(e.scaleY = n.height / t.offsetHeight || 1),
									(e.scrollLeft = 0),
									(e.scrollTop = 0);
								var r = window.getComputedStyle(t),
									o = 'border-box' === r.getPropertyValue('box-sizing');
								if (!1 === o) {
									var s = i(r, 'border-left-width'),
										a = i(r, 'border-right-width'),
										c = i(r, 'border-bottom-width'),
										h = i(r, 'border-top-width');
									(e.border = [s, a, h, c]), (e.x1 += s), (e.y1 += h), (e.width -= a + s), (e.height -= c + h);
								}
								(e.x2 = e.x1 + e.width), (e.y2 = e.y1 + e.height);
								var l = r.getPropertyValue('position'),
									u = 'fixed' === l ? t : t.parentNode;
								while (null !== u) {
									if (u === document.body) break;
									if (void 0 === u.scrollTop) break;
									(r = window.getComputedStyle(u)), (l = r.getPropertyValue('position'));
									if ('absolute' === l);
									else {
										if ('fixed' === l) {
											(e.scrollTop -= u.parentNode.scrollTop), (e.scrollLeft -= u.parentNode.scrollLeft);
											break;
										}
										(e.scrollLeft += u.scrollLeft), (e.scrollTop += u.scrollTop);
									}
									u = u.parentNode;
								}
								return (
									(e.scrollBodyLeft = void 0 !== window.pageXOffset ? window.pageXOffset : (document.documentElement || document.body.parentNode || document.body).scrollLeft),
									(e.scrollBodyTop = void 0 !== window.pageYOffset ? window.pageYOffset : (document.documentElement || document.body.parentNode || document.body).scrollTop),
									(e.scrollLeft -= e.scrollBodyLeft),
									(e.scrollTop -= e.scrollBodyTop),
									e
								);
							}),
							(function () {
								var e,
									i = navigator.userAgent.toLowerCase(),
									n = -1 !== i.indexOf('macintosh');
								(e = n && -1 !== i.indexOf('khtml') ? { 91: !0, 93: !0 } : n && -1 !== i.indexOf('firefox') ? { 224: !0 } : { 17: !0 }),
									(t.metaTrackerReset = function () {
										(r.fnKey = t.fnKey = !1),
											(r.metaKey = t.metaKey = !1),
											(r.escKey = t.escKey = !1),
											(r.ctrlKey = t.ctrlKey = !1),
											(r.shiftKey = t.shiftKey = !1),
											(r.altKey = t.altKey = !1);
									})(),
									(t.metaTracker = function (i) {
										var n = 'keydown' === i.type;
										27 === i.keyCode && (r.escKey = t.escKey = n),
											e[i.keyCode] && (r.metaKey = t.metaKey = n),
											(r.ctrlKey = t.ctrlKey = i.ctrlKey),
											(r.shiftKey = t.shiftKey = i.shiftKey),
											(r.altKey = t.altKey = i.altKey);
									});
							})(),
							t
						);
					})(r.proxy)),
					'undefined' === typeof r)
				)
					r = {};
				if (
					((r.MutationObserver = (function () {
						var t = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver,
							e =
								!t &&
								(function () {
									var t = document.createElement('p'),
										e = !1,
										i = function () {
											e = !0;
										};
									if (t.addEventListener) t.addEventListener('DOMAttrModified', i, !1);
									else {
										if (!t.attachEvent) return !1;
										t.attachEvent('onDOMAttrModified', i);
									}
									return t.setAttribute('id', 'target'), e;
								})();
						return function (i, n) {
							if (t) {
								var o = { subtree: !1, attributes: !0 },
									s = new t(function (t) {
										t.forEach(function (t) {
											n.call(t.target, t.attributeName);
										});
									});
								s.observe(i, o);
							} else
								e
									? r.add(i, 'DOMAttrModified', function (t) {
											n.call(i, t.attrName);
									  })
									: 'onpropertychange' in document.body &&
									  r.add(i, 'propertychange', function (t) {
											n.call(i, window.event.propertyName);
									  });
						};
					})()),
					'undefined' === typeof r)
				)
					r = {};
				if (
					('undefined' === typeof r.proxy && (r.proxy = {}),
					(r.proxy = (function (t) {
						'use strict';
						return (
							(t.click = function (e) {
								(e.gesture = e.gesture || 'click'),
									(e.maxFingers = e.maxFingers || e.fingers || 1),
									(e.onPointerDown = function (n) {
										t.pointerStart(n, i, e) && r.add(e.target, 'mouseup', e.onPointerUp);
									}),
									(e.onPointerUp = function (n) {
										if (t.pointerEnd(n, i, e)) {
											r.remove(e.target, 'mouseup', e.onPointerUp);
											var o = n.changedTouches || t.getCoords(n),
												s = o[0],
												a = e.bbox,
												c = t.getBoundingBox(e.target),
												h = s.pageY - c.scrollBodyTop,
												l = s.pageX - c.scrollBodyLeft;
											if (l > a.x1 && h > a.y1 && l < a.x2 && h < a.y2 && a.scrollTop === c.scrollTop) {
												for (var u in e.tracker) break;
												var f = e.tracker[u];
												(i.x = f.start.x), (i.y = f.start.y), e.listener(n, i);
											}
										}
									});
								var i = t.pointerSetup(e);
								return (i.state = 'click'), r.add(e.target, 'mousedown', e.onPointerDown), i;
							}),
							(r.Gesture = r.Gesture || {}),
							(r.Gesture._gestureHandlers = r.Gesture._gestureHandlers || {}),
							(r.Gesture._gestureHandlers.click = t.click),
							t
						);
					})(r.proxy)),
					'undefined' === typeof r)
				)
					r = {};
				if (
					('undefined' === typeof r.proxy && (r.proxy = {}),
					(r.proxy = (function (t) {
						'use strict';
						return (
							(t.dbltap = t.dblclick =
								function (e) {
									(e.gesture = e.gesture || 'dbltap'), (e.maxFingers = e.maxFingers || e.fingers || 1);
									var i,
										n,
										o,
										s,
										a,
										c = 700;
									(e.onPointerDown = function (l) {
										var u = l.changedTouches || t.getCoords(l);
										i && !n
											? ((a = u[0]), (n = new Date().getTime() - i))
											: ((s = u[0]),
											  (i = new Date().getTime()),
											  (n = 0),
											  clearTimeout(o),
											  (o = setTimeout(function () {
													i = 0;
											  }, c))),
											t.pointerStart(l, h, e) && (r.add(e.target, 'mousemove', e.onPointerMove).listener(l), r.add(e.target, 'mouseup', e.onPointerUp));
									}),
										(e.onPointerMove = function (c) {
											if (i && !n) {
												var h = c.changedTouches || t.getCoords(c);
												a = h[0];
											}
											var l = e.bbox,
												u = a.pageX - l.x1,
												f = a.pageY - l.y1;
											(u > 0 && u < l.width && f > 0 && f < l.height && Math.abs(a.pageX - s.pageX) <= 25 && Math.abs(a.pageY - s.pageY) <= 25) ||
												(r.remove(e.target, 'mousemove', e.onPointerMove), clearTimeout(o), (i = n = 0));
										}),
										(e.onPointerUp = function (s) {
											if ((t.pointerEnd(s, h, e) && (r.remove(e.target, 'mousemove', e.onPointerMove), r.remove(e.target, 'mouseup', e.onPointerUp)), i && n)) {
												if (n <= c) {
													for (var a in ((h.state = e.gesture), e.tracker)) break;
													var l = e.tracker[a];
													(h.x = l.start.x), (h.y = l.start.y), e.listener(s, h);
												}
												clearTimeout(o), (i = n = 0);
											}
										});
									var h = t.pointerSetup(e);
									return (h.state = 'dblclick'), r.add(e.target, 'mousedown', e.onPointerDown), h;
								}),
							(r.Gesture = r.Gesture || {}),
							(r.Gesture._gestureHandlers = r.Gesture._gestureHandlers || {}),
							(r.Gesture._gestureHandlers.dbltap = t.dbltap),
							(r.Gesture._gestureHandlers.dblclick = t.dblclick),
							t
						);
					})(r.proxy)),
					'undefined' === typeof r)
				)
					r = {};
				if (
					('undefined' === typeof r.proxy && (r.proxy = {}),
					(r.proxy = (function (t) {
						'use strict';
						return (
							(t.dragElement = function (e, i) {
								t.drag({
									event: i,
									target: e,
									position: 'move',
									listener: function (t, i) {
										(e.style.left = i.x + 'px'), (e.style.top = i.y + 'px'), r.prevent(t);
									}
								});
							}),
							(t.drag = function (e) {
								(e.gesture = 'drag'),
									(e.onPointerDown = function (n) {
										t.pointerStart(n, i, e) && (e.monitor || (r.add(e.doc, 'mousemove', e.onPointerMove), r.add(e.doc, 'mouseup', e.onPointerUp))), e.onPointerMove(n, 'down');
									}),
									(e.onPointerMove = function (n, r) {
										if (!e.tracker) return e.onPointerDown(n);
										e.bbox;
										for (var o = n.changedTouches || t.getCoords(n), s = o.length, a = 0; a < s; a++) {
											var c = o[a],
												h = c.identifier || 1 / 0,
												l = e.tracker[h];
											l &&
												((l.pageX = c.pageX),
												(l.pageY = c.pageY),
												(i.state = r || 'move'),
												(i.identifier = h),
												(i.start = l.start),
												(i.fingers = e.fingers),
												'differenceFromLast' === e.position
													? ((i.x = l.pageX - l.offsetX), (i.y = l.pageY - l.offsetY), (l.offsetX = l.pageX), (l.offsetY = l.pageY))
													: ((i.x = l.pageX - l.offsetX), (i.y = l.pageY - l.offsetY)),
												e.listener(n, i));
										}
									}),
									(e.onPointerUp = function (n) {
										t.pointerEnd(n, i, e, e.onPointerMove) && (e.monitor || (r.remove(e.doc, 'mousemove', e.onPointerMove), r.remove(e.doc, 'mouseup', e.onPointerUp)));
									});
								var i = t.pointerSetup(e);
								return (
									e.event
										? e.onPointerDown(e.event)
										: (r.add(e.target, 'mousedown', e.onPointerDown), e.monitor && (r.add(e.doc, 'mousemove', e.onPointerMove), r.add(e.doc, 'mouseup', e.onPointerUp))),
									i
								);
							}),
							(r.Gesture = r.Gesture || {}),
							(r.Gesture._gestureHandlers = r.Gesture._gestureHandlers || {}),
							(r.Gesture._gestureHandlers.drag = t.drag),
							t
						);
					})(r.proxy)),
					'undefined' === typeof r)
				)
					r = {};
				if (
					('undefined' === typeof r.proxy && (r.proxy = {}),
					(r.proxy = (function (t) {
						'use strict';
						var e = Math.PI / 180,
							i = function (t, e) {
								var i = 0,
									n = 0,
									r = 0;
								for (var o in e) {
									var s = e[o];
									s.up || ((i += s.move.x), (n += s.move.y), r++);
								}
								return (t.x = i /= r), (t.y = n /= r), t;
							};
						return (
							(t.gesture = function (n) {
								(n.gesture = n.gesture || 'gesture'),
									(n.minFingers = n.minFingers || n.fingers || 2),
									(n.onPointerDown = function (e) {
										var s = n.fingers;
										if (
											(t.pointerStart(e, o, n) && (r.add(n.doc, 'mousemove', n.onPointerMove), r.add(n.doc, 'mouseup', n.onPointerUp)),
											n.fingers === n.minFingers && s !== n.fingers)
										) {
											(o.fingers = n.minFingers), (o.scale = 1), (o.rotation = 0), (o.state = 'start');
											var a = '';
											for (var c in n.tracker) a += c;
											(o.identifier = parseInt(a)), i(o, n.tracker), n.listener(e, o);
										}
									}),
									(n.onPointerMove = function (r, s) {
										for (var a = n.bbox, c = n.tracker, h = r.changedTouches || t.getCoords(r), l = h.length, u = 0; u < l; u++) {
											var f = h[u],
												d = f.identifier || 1 / 0,
												p = c[d];
											p && ((p.move.x = f.pageX - a.x1), (p.move.y = f.pageY - a.y1));
										}
										if (!(n.fingers < n.minFingers)) {
											h = [];
											var g = 0,
												v = 0;
											for (var d in (i(o, c), c)) {
												f = c[d];
												if (!f.up) {
													var m = f.start;
													if (!m.distance) {
														var y = m.x - o.x,
															b = m.y - o.y;
														(m.distance = Math.sqrt(y * y + b * b)), (m.angle = Math.atan2(y, b) / e);
													}
													(y = f.move.x - o.x), (b = f.move.y - o.y);
													var x = Math.sqrt(y * y + b * b);
													0 !== m.distance && (g += x / m.distance);
													var _ = Math.atan2(y, b) / e,
														w = ((m.angle - _ + 360) % 360) - 180;
													(f.DEG2 = f.DEG1),
														(f.DEG1 = w > 0 ? w : -w),
														'undefined' !== typeof f.DEG2 && (w > 0 ? (f.rotation += f.DEG1 - f.DEG2) : (f.rotation -= f.DEG1 - f.DEG2), (v += f.rotation)),
														h.push(f.move);
												}
											}
											(o.touches = h), (o.fingers = n.fingers), (o.scale = g / n.fingers), (o.rotation = v / n.fingers), (o.state = 'change'), n.listener(r, o);
										}
									}),
									(n.onPointerUp = function (e) {
										var i = n.fingers;
										t.pointerEnd(e, o, n) && (r.remove(n.doc, 'mousemove', n.onPointerMove), r.remove(n.doc, 'mouseup', n.onPointerUp)),
											i === n.minFingers && n.fingers < n.minFingers && ((o.fingers = n.fingers), (o.state = 'end'), n.listener(e, o));
									});
								var o = t.pointerSetup(n);
								return r.add(n.target, 'mousedown', n.onPointerDown), o;
							}),
							(r.Gesture = r.Gesture || {}),
							(r.Gesture._gestureHandlers = r.Gesture._gestureHandlers || {}),
							(r.Gesture._gestureHandlers.gesture = t.gesture),
							t
						);
					})(r.proxy)),
					'undefined' === typeof r)
				)
					r = {};
				if (
					('undefined' === typeof r.proxy && (r.proxy = {}),
					(r.proxy = (function (t) {
						'use strict';
						return (
							(t.pointerdown =
								t.pointermove =
								t.pointerup =
									function (e) {
										if (((e.gesture = e.gesture || 'pointer'), !e.target.isPointerEmitter)) {
											var i = !0;
											(e.onPointerDown = function (t) {
												(i = !1), (n.gesture = 'pointerdown'), e.listener(t, n);
											}),
												(e.onPointerMove = function (t) {
													(n.gesture = 'pointermove'), e.listener(t, n, i);
												}),
												(e.onPointerUp = function (t) {
													(i = !0), (n.gesture = 'pointerup'), e.listener(t, n, !0);
												});
											var n = t.pointerSetup(e);
											return (
												r.add(e.target, 'mousedown', e.onPointerDown),
												r.add(e.target, 'mousemove', e.onPointerMove),
												r.add(e.doc, 'mouseup', e.onPointerUp),
												(e.target.isPointerEmitter = !0),
												n
											);
										}
									}),
							(r.Gesture = r.Gesture || {}),
							(r.Gesture._gestureHandlers = r.Gesture._gestureHandlers || {}),
							(r.Gesture._gestureHandlers.pointerdown = t.pointerdown),
							(r.Gesture._gestureHandlers.pointermove = t.pointermove),
							(r.Gesture._gestureHandlers.pointerup = t.pointerup),
							t
						);
					})(r.proxy)),
					'undefined' === typeof r)
				)
					r = {};
				if (
					('undefined' === typeof r.proxy && (r.proxy = {}),
					(r.proxy = (function (t) {
						'use strict';
						return (
							(t.shake = function (t) {
								var e = {
										gesture: 'devicemotion',
										acceleration: {},
										accelerationIncludingGravity: {},
										target: t.target,
										listener: t.listener,
										remove: function () {
											window.removeEventListener('devicemotion', h, !1);
										}
									},
									i = 4,
									n = 1e3,
									r = 200,
									o = 3,
									s = new Date().getTime(),
									a = { x: 0, y: 0, z: 0 },
									c = { x: { count: 0, value: 0 }, y: { count: 0, value: 0 }, z: { count: 0, value: 0 } },
									h = function (h) {
										var l = 0.8,
											u = h.accelerationIncludingGravity;
										if (
											((a.x = l * a.x + (1 - l) * u.x),
											(a.y = l * a.y + (1 - l) * u.y),
											(a.z = l * a.z + (1 - l) * u.z),
											(e.accelerationIncludingGravity = a),
											(e.acceleration.x = u.x - a.x),
											(e.acceleration.y = u.y - a.y),
											(e.acceleration.z = u.z - a.z),
											'devicemotion' !== t.gesture)
										)
											for (var f = 'xyz', d = new Date().getTime(), p = 0, g = f.length; p < g; p++) {
												var v = f[p],
													m = e.acceleration[v],
													y = c[v],
													b = Math.abs(m);
												if (!(d - s < n) && b > i) {
													var x = (d * m) / b,
														_ = Math.abs(x + y.value);
													y.value && _ < r
														? ((y.value = x), y.count++, y.count === o && (t.listener(h, e), (s = d), (y.value = 0), (y.count = 0)))
														: ((y.value = x), (y.count = 1));
												}
											}
										else t.listener(h, e);
									};
								if (window.addEventListener) return window.addEventListener('devicemotion', h, !1), e;
							}),
							(r.Gesture = r.Gesture || {}),
							(r.Gesture._gestureHandlers = r.Gesture._gestureHandlers || {}),
							(r.Gesture._gestureHandlers.shake = t.shake),
							t
						);
					})(r.proxy)),
					'undefined' === typeof r)
				)
					r = {};
				if (
					('undefined' === typeof r.proxy && (r.proxy = {}),
					(r.proxy = (function (t) {
						'use strict';
						var e = Math.PI / 180;
						return (
							(t.swipe = function (i) {
								(i.snap = i.snap || 90),
									(i.threshold = i.threshold || 1),
									(i.gesture = i.gesture || 'swipe'),
									(i.onPointerDown = function (e) {
										t.pointerStart(e, n, i) && (r.add(i.doc, 'mousemove', i.onPointerMove).listener(e), r.add(i.doc, 'mouseup', i.onPointerUp));
									}),
									(i.onPointerMove = function (e) {
										for (var n = e.changedTouches || t.getCoords(e), r = n.length, o = 0; o < r; o++) {
											var s = n[o],
												a = s.identifier || 1 / 0,
												c = i.tracker[a];
											c && ((c.move.x = s.pageX), (c.move.y = s.pageY), (c.moveTime = new Date().getTime()));
										}
									}),
									(i.onPointerUp = function (o) {
										if (t.pointerEnd(o, n, i)) {
											var s, a;
											r.remove(i.doc, 'mousemove', i.onPointerMove), r.remove(i.doc, 'mouseup', i.onPointerUp);
											var c = { x: 0, y: 0 },
												h = 0,
												l = 0,
												u = 0;
											for (var f in i.tracker) {
												var d = i.tracker[f],
													p = d.move.x - d.start.x,
													g = d.move.y - d.start.y;
												(h += d.move.x), (l += d.move.y), (c.x += d.start.x), (c.y += d.start.y), u++;
												var v = Math.sqrt(p * p + g * g),
													m = d.moveTime - d.startTime,
													y = Math.atan2(p, g) / e + 180,
													b = m ? v / m : 0;
												if ('undefined' === typeof a) (a = y), (s = b);
												else {
													if (!(Math.abs(y - a) <= 20)) return;
													(a = (a + y) / 2), (s = (s + b) / 2);
												}
											}
											var x = i.gestureFingers;
											i.minFingers <= x &&
												i.maxFingers >= x &&
												s > i.threshold &&
												((c.x /= u),
												(c.y /= u),
												(n.start = c),
												(n.x = h / u),
												(n.y = l / u),
												(n.angle = -((((a / i.snap + 0.5) >> 0) * i.snap || 360) - 360)),
												(n.velocity = s),
												(n.fingers = x),
												(n.state = 'swipe'),
												i.listener(o, n));
										}
									});
								var n = t.pointerSetup(i);
								return r.add(i.target, 'mousedown', i.onPointerDown), n;
							}),
							(r.Gesture = r.Gesture || {}),
							(r.Gesture._gestureHandlers = r.Gesture._gestureHandlers || {}),
							(r.Gesture._gestureHandlers.swipe = t.swipe),
							t
						);
					})(r.proxy)),
					'undefined' === typeof r)
				)
					r = {};
				if (
					('undefined' === typeof r.proxy && (r.proxy = {}),
					(r.proxy = (function (t) {
						'use strict';
						return (
							(t.longpress = function (e) {
								return (e.gesture = 'longpress'), t.tap(e);
							}),
							(t.tap = function (e) {
								var i, n;
								(e.delay = e.delay || 500),
									(e.timeout = e.timeout || 250),
									(e.driftDeviance = e.driftDeviance || 10),
									(e.gesture = e.gesture || 'tap'),
									(e.onPointerDown = function (s) {
										if (t.pointerStart(s, o, e)) {
											if (((i = new Date().getTime()), r.add(e.doc, 'mousemove', e.onPointerMove).listener(s), r.add(e.doc, 'mouseup', e.onPointerUp), 'longpress' !== e.gesture))
												return;
											n = setTimeout(function () {
												if (!(s.cancelBubble && ++s.cancelBubbleCount > 1)) {
													var t = 0;
													for (var i in e.tracker) {
														var n = e.tracker[i];
														if (!0 === n.end) return;
														if (e.cancel) return;
														t++;
													}
													e.minFingers <= t && e.maxFingers >= t && ((o.state = 'start'), (o.fingers = t), (o.x = n.start.x), (o.y = n.start.y), e.listener(s, o));
												}
											}, e.delay);
										}
									}),
									(e.onPointerMove = function (i) {
										for (var n = e.bbox, o = i.changedTouches || t.getCoords(i), s = o.length, a = 0; a < s; a++) {
											var c = o[a],
												h = c.identifier || 1 / 0,
												l = e.tracker[h];
											if (l) {
												var u = c.pageX - n.x1 - parseInt(window.scrollX),
													f = c.pageY - n.y1 - parseInt(window.scrollY),
													d = u - l.start.x,
													p = f - l.start.y,
													g = Math.sqrt(d * d + p * p);
												if (!(u > 0 && u < n.width && f > 0 && f < n.height && g <= e.driftDeviance))
													return r.remove(e.doc, 'mousemove', e.onPointerMove), void (e.cancel = !0);
											}
										}
									}),
									(e.onPointerUp = function (s) {
										if (t.pointerEnd(s, o, e)) {
											if (
												(clearTimeout(n), r.remove(e.doc, 'mousemove', e.onPointerMove), r.remove(e.doc, 'mouseup', e.onPointerUp), s.cancelBubble && ++s.cancelBubbleCount > 1)
											)
												return;
											if ('longpress' === e.gesture) return void ('start' === o.state && ((o.state = 'end'), e.listener(s, o)));
											if (e.cancel) return;
											if (new Date().getTime() - i > e.timeout) return;
											var a = e.gestureFingers;
											e.minFingers <= a && e.maxFingers >= a && ((o.state = 'tap'), (o.fingers = e.gestureFingers), e.listener(s, o));
										}
									});
								var o = t.pointerSetup(e);
								return r.add(e.target, 'mousedown', e.onPointerDown), o;
							}),
							(r.Gesture = r.Gesture || {}),
							(r.Gesture._gestureHandlers = r.Gesture._gestureHandlers || {}),
							(r.Gesture._gestureHandlers.tap = t.tap),
							(r.Gesture._gestureHandlers.longpress = t.longpress),
							t
						);
					})(r.proxy)),
					'undefined' === typeof r)
				)
					r = {};
				if (
					('undefined' === typeof r.proxy && (r.proxy = {}),
					(r.proxy = (function (t) {
						'use strict';
						return (
							(t.wheelPreventElasticBounce = function (t) {
								t &&
									('string' === typeof t && (t = document.querySelector(t)),
									r.add(t, 'wheel', function (t, e) {
										e.preventElasticBounce(), r.stop(t);
									}));
							}),
							(t.wheel = function (t) {
								var e,
									i = t.timeout || 150,
									n = 0,
									o = {
										gesture: 'wheel',
										state: 'start',
										wheelDelta: 0,
										target: t.target,
										listener: t.listener,
										preventElasticBounce: function (t) {
											var e = this.target,
												i = e.scrollTop,
												n = i + e.offsetHeight,
												o = e.scrollHeight;
											((n === o && this.wheelDelta <= 0) || (0 === i && this.wheelDelta >= 0)) && r.cancel(t), r.stop(t);
										},
										add: function () {
											t.target[a](h, s, !1);
										},
										remove: function () {
											t.target[c](h, s, !1);
										}
									},
									s = function (r) {
										(r = r || window.event),
											(o.state = n++ ? 'change' : 'start'),
											(o.wheelDelta = r.detail ? -20 * r.detail : r.wheelDelta),
											t.listener(r, o),
											clearTimeout(e),
											(e = setTimeout(function () {
												(n = 0), (o.state = 'end'), (o.wheelDelta = 0), t.listener(r, o);
											}, i));
									},
									a = document.addEventListener ? 'addEventListener' : 'attachEvent',
									c = document.removeEventListener ? 'removeEventListener' : 'detachEvent',
									h = r.getEventSupport('mousewheel') ? 'mousewheel' : 'DOMMouseScroll';
								return t.target[a](h, s, !1), o;
							}),
							(r.Gesture = r.Gesture || {}),
							(r.Gesture._gestureHandlers = r.Gesture._gestureHandlers || {}),
							(r.Gesture._gestureHandlers.wheel = t.wheel),
							t
						);
					})(r.proxy)),
					'undefined' === typeof o)
				)
					var o = {};
				function s(t) {
					var e = t.targetCanvas,
						i = e.width,
						n = e.height,
						r = t.destinationWidth,
						o = t.destinationHeight;
					(i === r && n === o) || ((e.width = r), (e.height = o));
				}
				function a(t, e) {
					var i = t.canvas,
						n = e.targetCanvas,
						r = n.getContext('2d');
					r.translate(0, n.height), r.scale(1, -1);
					var o = i.height - n.height;
					r.drawImage(i, 0, o, n.width, n.height, 0, 0, n.width, n.height);
				}
				function c(t, e) {
					var i = e.targetCanvas,
						n = i.getContext('2d'),
						r = e.destinationWidth,
						o = e.destinationHeight,
						s = r * o * 4,
						a = new Uint8Array(this.imageBuffer, 0, s),
						c = new Uint8ClampedArray(this.imageBuffer, 0, s);
					t.readPixels(0, 0, r, o, t.RGBA, t.UNSIGNED_BYTE, a);
					var h = new ImageData(c, r, o);
					n.putImageData(h, 0, 0);
				}
				'undefined' === typeof o.proxy && (o.proxy = {}),
					(o.proxy = (function (t) {
						'use strict';
						return (
							(t.orientation = function (t) {
								var e = {
										gesture: 'orientationchange',
										previous: null,
										current: window.orientation,
										target: t.target,
										listener: t.listener,
										remove: function () {
											window.removeEventListener('orientationchange', i, !1);
										}
									},
									i = function (i) {
										(e.previous = e.current), (e.current = window.orientation), null === e.previous || e.previous == e.current || t.listener(i, e);
									};
								return window.DeviceOrientationEvent && window.addEventListener('orientationchange', i, !1), e;
							}),
							(o.Gesture = o.Gesture || {}),
							(o.Gesture._gestureHandlers = o.Gesture._gestureHandlers || {}),
							(o.Gesture._gestureHandlers.orientation = t.orientation),
							t
						);
					})(o.proxy)),
					(function () {
						function t(t, e) {
							if (this.__eventListeners[t]) {
								var i = this.__eventListeners[t];
								e ? (i[i.indexOf(e)] = !1) : n.util.array.fill(i, !1);
							}
						}
						function e(t, e) {
							if ((this.__eventListeners || (this.__eventListeners = {}), 1 === arguments.length)) for (var i in t) this.on(i, t[i]);
							else this.__eventListeners[t] || (this.__eventListeners[t] = []), this.__eventListeners[t].push(e);
							return this;
						}
						function i(t, e) {
							var i = function () {
								e.apply(this, arguments), this.off(t, i);
							}.bind(this);
							this.on(t, i);
						}
						function r(t, e) {
							if (1 === arguments.length) for (var n in t) i.call(this, n, t[n]);
							else i.call(this, t, e);
							return this;
						}
						function o(e, i) {
							if (!this.__eventListeners) return this;
							if (0 === arguments.length) for (e in this.__eventListeners) t.call(this, e);
							else if (1 === arguments.length && 'object' === typeof arguments[0]) for (var n in e) t.call(this, n, e[n]);
							else t.call(this, e, i);
							return this;
						}
						function s(t, e) {
							if (!this.__eventListeners) return this;
							var i = this.__eventListeners[t];
							if (!i) return this;
							for (var n = 0, r = i.length; n < r; n++) i[n] && i[n].call(this, e || {});
							return (
								(this.__eventListeners[t] = i.filter(function (t) {
									return !1 !== t;
								})),
								this
							);
						}
						n.Observable = { fire: s, on: e, once: r, off: o };
					})(),
					(n.Collection = {
						_objects: [],
						add: function () {
							if ((this._objects.push.apply(this._objects, arguments), this._onObjectAdded)) for (var t = 0, e = arguments.length; t < e; t++) this._onObjectAdded(arguments[t]);
							return this.renderOnAddRemove && this.requestRenderAll(), this;
						},
						insertAt: function (t, e, i) {
							var n = this._objects;
							return i ? (n[e] = t) : n.splice(e, 0, t), this._onObjectAdded && this._onObjectAdded(t), this.renderOnAddRemove && this.requestRenderAll(), this;
						},
						remove: function () {
							for (var t, e = this._objects, i = !1, n = 0, r = arguments.length; n < r; n++)
								(t = e.indexOf(arguments[n])), -1 !== t && ((i = !0), e.splice(t, 1), this._onObjectRemoved && this._onObjectRemoved(arguments[n]));
							return this.renderOnAddRemove && i && this.requestRenderAll(), this;
						},
						forEachObject: function (t, e) {
							for (var i = this.getObjects(), n = 0, r = i.length; n < r; n++) t.call(e, i[n], n, i);
							return this;
						},
						getObjects: function (t) {
							return 'undefined' === typeof t
								? this._objects.concat()
								: this._objects.filter(function (e) {
										return e.type === t;
								  });
						},
						item: function (t) {
							return this._objects[t];
						},
						isEmpty: function () {
							return 0 === this._objects.length;
						},
						size: function () {
							return this._objects.length;
						},
						contains: function (t, e) {
							return (
								this._objects.indexOf(t) > -1 ||
								(!!e &&
									this._objects.some(function (e) {
										return 'function' === typeof e.contains && e.contains(t, !0);
									}))
							);
						},
						complexity: function () {
							return this._objects.reduce(function (t, e) {
								return (t += e.complexity ? e.complexity() : 0), t;
							}, 0);
						}
					}),
					(n.CommonMethods = {
						_setOptions: function (t) {
							for (var e in t) this.set(e, t[e]);
						},
						_initGradient: function (t, e) {
							!t || !t.colorStops || t instanceof n.Gradient || this.set(e, new n.Gradient(t));
						},
						_initPattern: function (t, e, i) {
							!t || !t.source || t instanceof n.Pattern ? i && i() : this.set(e, new n.Pattern(t, i));
						},
						_setObject: function (t) {
							for (var e in t) this._set(e, t[e]);
						},
						set: function (t, e) {
							return 'object' === typeof t ? this._setObject(t) : this._set(t, e), this;
						},
						_set: function (t, e) {
							this[t] = e;
						},
						toggle: function (t) {
							var e = this.get(t);
							return 'boolean' === typeof e && this.set(t, !e), this;
						},
						get: function (t) {
							return this[t];
						}
					}),
					(function (t) {
						var e = Math.sqrt,
							i = Math.atan2,
							r = Math.pow,
							o = Math.PI / 180,
							s = Math.PI / 2;
						n.util = {
							cos: function (t) {
								if (0 === t) return 1;
								t < 0 && (t = -t);
								var e = t / s;
								switch (e) {
									case 1:
									case 3:
										return 0;
									case 2:
										return -1;
								}
								return Math.cos(t);
							},
							sin: function (t) {
								if (0 === t) return 0;
								var e = t / s,
									i = 1;
								switch ((t < 0 && (i = -1), e)) {
									case 1:
										return i;
									case 2:
										return 0;
									case 3:
										return -i;
								}
								return Math.sin(t);
							},
							removeFromArray: function (t, e) {
								var i = t.indexOf(e);
								return -1 !== i && t.splice(i, 1), t;
							},
							getRandomInt: function (t, e) {
								return Math.floor(Math.random() * (e - t + 1)) + t;
							},
							degreesToRadians: function (t) {
								return t * o;
							},
							radiansToDegrees: function (t) {
								return t / o;
							},
							rotatePoint: function (t, e, i) {
								var r = new n.Point(t.x - e.x, t.y - e.y),
									o = n.util.rotateVector(r, i);
								return new n.Point(o.x, o.y).addEquals(e);
							},
							rotateVector: function (t, e) {
								var i = n.util.sin(e),
									r = n.util.cos(e),
									o = t.x * r - t.y * i,
									s = t.x * i + t.y * r;
								return { x: o, y: s };
							},
							createVector: function (t, e) {
								return new n.Point(e.x - t.x, e.y - t.y);
							},
							calcAngleBetweenVectors: function (t, e) {
								return Math.acos((t.x * e.x + t.y * e.y) / (Math.hypot(t.x, t.y) * Math.hypot(e.x, e.y)));
							},
							getHatVector: function (t) {
								return new n.Point(t.x, t.y).multiply(1 / Math.hypot(t.x, t.y));
							},
							getBisector: function (t, e, i) {
								var r = n.util.createVector(t, e),
									o = n.util.createVector(t, i),
									s = n.util.calcAngleBetweenVectors(r, o),
									a = n.util.calcAngleBetweenVectors(n.util.rotateVector(r, s), o),
									c = (s * (0 === a ? 1 : -1)) / 2;
								return { vector: n.util.getHatVector(n.util.rotateVector(r, c)), angle: s };
							},
							projectStrokeOnPoints: function (t, e, i) {
								var r = [],
									o = e.strokeWidth / 2,
									s = e.strokeUniform ? new n.Point(1 / e.scaleX, 1 / e.scaleY) : new n.Point(1, 1),
									a = function (t) {
										var e = o / Math.hypot(t.x, t.y);
										return new n.Point(t.x * e * s.x, t.y * e * s.y);
									};
								return (
									t.length <= 1 ||
										t.forEach(function (c, h) {
											var l,
												u,
												f = new n.Point(c.x, c.y);
											0 === h
												? ((u = t[h + 1]), (l = i ? a(n.util.createVector(u, f)).addEquals(f) : t[t.length - 1]))
												: h === t.length - 1
												? ((l = t[h - 1]), (u = i ? a(n.util.createVector(l, f)).addEquals(f) : t[0]))
												: ((l = t[h - 1]), (u = t[h + 1]));
											var d,
												p,
												g = n.util.getBisector(f, l, u),
												v = g.vector,
												m = g.angle;
											if (
												'miter' === e.strokeLineJoin &&
												((d = -o / Math.sin(m / 2)), (p = new n.Point(v.x * d * s.x, v.y * d * s.y)), Math.hypot(p.x, p.y) / o <= e.strokeMiterLimit)
											)
												return r.push(f.add(p)), void r.push(f.subtract(p));
											(d = -o * Math.SQRT2), (p = new n.Point(v.x * d * s.x, v.y * d * s.y)), r.push(f.add(p)), r.push(f.subtract(p));
										}),
									r
								);
							},
							transformPoint: function (t, e, i) {
								return i ? new n.Point(e[0] * t.x + e[2] * t.y, e[1] * t.x + e[3] * t.y) : new n.Point(e[0] * t.x + e[2] * t.y + e[4], e[1] * t.x + e[3] * t.y + e[5]);
							},
							makeBoundingBoxFromPoints: function (t, e) {
								if (e) for (var i = 0; i < t.length; i++) t[i] = n.util.transformPoint(t[i], e);
								var r = [t[0].x, t[1].x, t[2].x, t[3].x],
									o = n.util.array.min(r),
									s = n.util.array.max(r),
									a = s - o,
									c = [t[0].y, t[1].y, t[2].y, t[3].y],
									h = n.util.array.min(c),
									l = n.util.array.max(c),
									u = l - h;
								return { left: o, top: h, width: a, height: u };
							},
							invertTransform: function (t) {
								var e = 1 / (t[0] * t[3] - t[1] * t[2]),
									i = [e * t[3], -e * t[1], -e * t[2], e * t[0]],
									r = n.util.transformPoint({ x: t[4], y: t[5] }, i, !0);
								return (i[4] = -r.x), (i[5] = -r.y), i;
							},
							toFixed: function (t, e) {
								return parseFloat(Number(t).toFixed(e));
							},
							parseUnit: function (t, e) {
								var i = /\D{0,2}$/.exec(t),
									r = parseFloat(t);
								switch ((e || (e = n.Text.DEFAULT_SVG_FONT_SIZE), i[0])) {
									case 'mm':
										return (r * n.DPI) / 25.4;
									case 'cm':
										return (r * n.DPI) / 2.54;
									case 'in':
										return r * n.DPI;
									case 'pt':
										return (r * n.DPI) / 72;
									case 'pc':
										return ((r * n.DPI) / 72) * 12;
									case 'em':
										return r * e;
									default:
										return r;
								}
							},
							falseFunction: function () {
								return !1;
							},
							getKlass: function (t, e) {
								return (t = n.util.string.camelize(t.charAt(0).toUpperCase() + t.slice(1))), n.util.resolveNamespace(e)[t];
							},
							getSvgAttributes: function (t) {
								var e = ['instantiated_by_use', 'style', 'id', 'class'];
								switch (t) {
									case 'linearGradient':
										e = e.concat(['x1', 'y1', 'x2', 'y2', 'gradientUnits', 'gradientTransform']);
										break;
									case 'radialGradient':
										e = e.concat(['gradientUnits', 'gradientTransform', 'cx', 'cy', 'r', 'fx', 'fy', 'fr']);
										break;
									case 'stop':
										e = e.concat(['offset', 'stop-color', 'stop-opacity']);
										break;
								}
								return e;
							},
							resolveNamespace: function (e) {
								if (!e) return n;
								var i,
									r = e.split('.'),
									o = r.length,
									s = t || n.window;
								for (i = 0; i < o; ++i) s = s[r[i]];
								return s;
							},
							loadImage: function (t, e, i, r) {
								if (t) {
									var o = n.util.createImage(),
										s = function () {
											e && e.call(i, o, !1), (o = o.onload = o.onerror = null);
										};
									(o.onload = s),
										(o.onerror = function () {
											n.log('Error loading ' + o.src), e && e.call(i, null, !0), (o = o.onload = o.onerror = null);
										}),
										0 !== t.indexOf('data') && void 0 !== r && null !== r && (o.crossOrigin = r),
										'data:image/svg' === t.substring(0, 14) && ((o.onload = null), n.util.loadImageInDom(o, s)),
										(o.src = t);
								} else e && e.call(i, t);
							},
							loadImageInDom: function (t, e) {
								var i = n.document.createElement('div');
								(i.style.width = i.style.height = '1px'),
									(i.style.left = i.style.top = '-100%'),
									(i.style.position = 'absolute'),
									i.appendChild(t),
									n.document.querySelector('body').appendChild(i),
									(t.onload = function () {
										e(), i.parentNode.removeChild(i), (i = null);
									});
							},
							enlivenObjects: function (t, e, i, r) {
								t = t || [];
								var o = [],
									s = 0,
									a = t.length;
								function c() {
									++s === a &&
										e &&
										e(
											o.filter(function (t) {
												return t;
											})
										);
								}
								a
									? t.forEach(function (t, e) {
											if (t && t.type) {
												var s = n.util.getKlass(t.type, i);
												s.fromObject(t, function (i, n) {
													n || (o[e] = i), r && r(t, i, n), c();
												});
											} else c();
									  })
									: e && e(o);
							},
							enlivenObjectEnlivables: function (t, e, i) {
								var r = n.Object.ENLIVEN_PROPS.filter(function (e) {
									return !!t[e];
								});
								n.util.enlivenObjects(
									r.map(function (e) {
										return t[e];
									}),
									function (t) {
										var n = {};
										r.forEach(function (i, r) {
											(n[i] = t[r]), e && (e[i] = t[r]);
										}),
											i && i(n);
									}
								);
							},
							enlivenPatterns: function (t, e) {
								function i() {
									++o === s && e && e(r);
								}
								t = t || [];
								var r = [],
									o = 0,
									s = t.length;
								s
									? t.forEach(function (t, e) {
											t && t.source
												? new n.Pattern(t, function (t) {
														(r[e] = t), i();
												  })
												: ((r[e] = t), i());
									  })
									: e && e(r);
							},
							groupSVGElements: function (t, e, i) {
								var r;
								return t && 1 === t.length
									? t[0]
									: (e && (e.width && e.height ? (e.centerPoint = { x: e.width / 2, y: e.height / 2 }) : (delete e.width, delete e.height)),
									  (r = new n.Group(t, e)),
									  'undefined' !== typeof i && (r.sourcePath = i),
									  r);
							},
							populateWithProperties: function (t, e, i) {
								if (i && Array.isArray(i)) for (var n = 0, r = i.length; n < r; n++) i[n] in t && (e[i[n]] = t[i[n]]);
							},
							createCanvasElement: function () {
								return n.document.createElement('canvas');
							},
							copyCanvasElement: function (t) {
								var e = n.util.createCanvasElement();
								return (e.width = t.width), (e.height = t.height), e.getContext('2d').drawImage(t, 0, 0), e;
							},
							toDataURL: function (t, e, i) {
								return t.toDataURL('image/' + e, i);
							},
							createImage: function () {
								return n.document.createElement('img');
							},
							multiplyTransformMatrices: function (t, e, i) {
								return [
									t[0] * e[0] + t[2] * e[1],
									t[1] * e[0] + t[3] * e[1],
									t[0] * e[2] + t[2] * e[3],
									t[1] * e[2] + t[3] * e[3],
									i ? 0 : t[0] * e[4] + t[2] * e[5] + t[4],
									i ? 0 : t[1] * e[4] + t[3] * e[5] + t[5]
								];
							},
							qrDecompose: function (t) {
								var n = i(t[1], t[0]),
									s = r(t[0], 2) + r(t[1], 2),
									a = e(s),
									c = (t[0] * t[3] - t[2] * t[1]) / a,
									h = i(t[0] * t[2] + t[1] * t[3], s);
								return { angle: n / o, scaleX: a, scaleY: c, skewX: h / o, skewY: 0, translateX: t[4], translateY: t[5] };
							},
							calcRotateMatrix: function (t) {
								if (!t.angle) return n.iMatrix.concat();
								var e = n.util.degreesToRadians(t.angle),
									i = n.util.cos(e),
									r = n.util.sin(e);
								return [i, r, -r, i, 0, 0];
							},
							calcDimensionsMatrix: function (t) {
								var e = 'undefined' === typeof t.scaleX ? 1 : t.scaleX,
									i = 'undefined' === typeof t.scaleY ? 1 : t.scaleY,
									r = [t.flipX ? -e : e, 0, 0, t.flipY ? -i : i, 0, 0],
									o = n.util.multiplyTransformMatrices,
									s = n.util.degreesToRadians;
								return t.skewX && (r = o(r, [1, 0, Math.tan(s(t.skewX)), 1], !0)), t.skewY && (r = o(r, [1, Math.tan(s(t.skewY)), 0, 1], !0)), r;
							},
							composeMatrix: function (t) {
								var e = [1, 0, 0, 1, t.translateX || 0, t.translateY || 0],
									i = n.util.multiplyTransformMatrices;
								return (
									t.angle && (e = i(e, n.util.calcRotateMatrix(t))),
									(1 !== t.scaleX || 1 !== t.scaleY || t.skewX || t.skewY || t.flipX || t.flipY) && (e = i(e, n.util.calcDimensionsMatrix(t))),
									e
								);
							},
							resetObjectTransform: function (t) {
								(t.scaleX = 1), (t.scaleY = 1), (t.skewX = 0), (t.skewY = 0), (t.flipX = !1), (t.flipY = !1), t.rotate(0);
							},
							saveObjectTransform: function (t) {
								return { scaleX: t.scaleX, scaleY: t.scaleY, skewX: t.skewX, skewY: t.skewY, angle: t.angle, left: t.left, flipX: t.flipX, flipY: t.flipY, top: t.top };
							},
							isTransparent: function (t, e, i, n) {
								n > 0 && (e > n ? (e -= n) : (e = 0), i > n ? (i -= n) : (i = 0));
								var r,
									o,
									s = !0,
									a = t.getImageData(e, i, 2 * n || 1, 2 * n || 1),
									c = a.data.length;
								for (r = 3; r < c; r += 4) if (((o = a.data[r]), (s = o <= 0), !1 === s)) break;
								return (a = null), s;
							},
							parsePreserveAspectRatioAttribute: function (t) {
								var e,
									i = 'meet',
									n = 'Mid',
									r = 'Mid',
									o = t.split(' ');
								return (
									o && o.length && ((i = o.pop()), 'meet' !== i && 'slice' !== i ? ((e = i), (i = 'meet')) : o.length && (e = o.pop())),
									(n = 'none' !== e ? e.slice(1, 4) : 'none'),
									(r = 'none' !== e ? e.slice(5, 8) : 'none'),
									{ meetOrSlice: i, alignX: n, alignY: r }
								);
							},
							clearFabricFontCache: function (t) {
								(t = (t || '').toLowerCase()), t ? n.charWidthsCache[t] && delete n.charWidthsCache[t] : (n.charWidthsCache = {});
							},
							limitDimsByArea: function (t, e) {
								var i = Math.sqrt(e * t),
									n = Math.floor(e / i);
								return { x: Math.floor(i), y: n };
							},
							capValue: function (t, e, i) {
								return Math.max(t, Math.min(e, i));
							},
							findScaleToFit: function (t, e) {
								return Math.min(e.width / t.width, e.height / t.height);
							},
							findScaleToCover: function (t, e) {
								return Math.max(e.width / t.width, e.height / t.height);
							},
							matrixToSVG: function (t) {
								return (
									'matrix(' +
									t
										.map(function (t) {
											return n.util.toFixed(t, n.Object.NUM_FRACTION_DIGITS);
										})
										.join(' ') +
									')'
								);
							},
							removeTransformFromObject: function (t, e) {
								var i = n.util.invertTransform(e),
									r = n.util.multiplyTransformMatrices(i, t.calcOwnMatrix());
								n.util.applyTransformToObject(t, r);
							},
							addTransformToObject: function (t, e) {
								n.util.applyTransformToObject(t, n.util.multiplyTransformMatrices(e, t.calcOwnMatrix()));
							},
							applyTransformToObject: function (t, e) {
								var i = n.util.qrDecompose(e),
									r = new n.Point(i.translateX, i.translateY);
								(t.flipX = !1),
									(t.flipY = !1),
									t.set('scaleX', i.scaleX),
									t.set('scaleY', i.scaleY),
									(t.skewX = i.skewX),
									(t.skewY = i.skewY),
									(t.angle = i.angle),
									t.setPositionByOrigin(r, 'center', 'center');
							},
							sizeAfterTransform: function (t, e, i) {
								var r = t / 2,
									o = e / 2,
									s = [
										{ x: -r, y: -o },
										{ x: r, y: -o },
										{ x: -r, y: o },
										{ x: r, y: o }
									],
									a = n.util.calcDimensionsMatrix(i),
									c = n.util.makeBoundingBoxFromPoints(s, a);
								return { x: c.width, y: c.height };
							},
							mergeClipPaths: function (t, e) {
								var i = t,
									r = e;
								i.inverted && !r.inverted && ((i = e), (r = t)),
									n.util.applyTransformToObject(r, n.util.multiplyTransformMatrices(n.util.invertTransform(i.calcTransformMatrix()), r.calcTransformMatrix()));
								var o = i.inverted && r.inverted;
								return o && (i.inverted = r.inverted = !1), new n.Group([i], { clipPath: r, inverted: o });
							},
							hasStyleChanged: function (t, e, i) {
								return (
									(i = i || !1),
									t.fill !== e.fill ||
										t.stroke !== e.stroke ||
										t.strokeWidth !== e.strokeWidth ||
										t.fontSize !== e.fontSize ||
										t.fontFamily !== e.fontFamily ||
										t.fontWeight !== e.fontWeight ||
										t.fontStyle !== e.fontStyle ||
										t.deltaY !== e.deltaY ||
										(i && (t.overline !== e.overline || t.underline !== e.underline || t.linethrough !== e.linethrough))
								);
							},
							stylesToArray: function (t, e) {
								t = n.util.object.clone(t, !0);
								for (var i = e.split('\n'), r = -1, o = {}, s = [], a = 0; a < i.length; a++)
									if (t[a])
										for (var c = 0; c < i[a].length; c++) {
											r++;
											var h = t[a][c];
											if (h) {
												var l = n.util.hasStyleChanged(o, h, !0);
												l ? s.push({ start: r, end: r + 1, style: h }) : s[s.length - 1].end++;
											}
											o = h || {};
										}
									else r += i[a].length;
								return s;
							},
							stylesFromArray: function (t, e) {
								if (!Array.isArray(t)) return t;
								for (var i = e.split('\n'), n = -1, r = 0, o = {}, s = 0; s < i.length; s++)
									for (var a = 0; a < i[s].length; a++)
										n++, t[r] && t[r].start <= n && n < t[r].end && ((o[s] = o[s] || {}), (o[s][a] = Object.assign({}, t[r].style)), n === t[r].end - 1 && r++);
								return o;
							}
						};
					})(e),
					(function () {
						var t = Array.prototype.join,
							e = { m: 2, l: 2, h: 1, v: 1, c: 6, s: 4, q: 4, t: 2, a: 7 },
							i = { m: 'l', M: 'L' };
						function r(t, e, i, r, o, s, a, c, h, l, u) {
							var f = n.util.cos(t),
								d = n.util.sin(t),
								p = n.util.cos(e),
								g = n.util.sin(e),
								v = i * o * p - r * s * g + a,
								m = r * o * p + i * s * g + c,
								y = l + h * (-i * o * d - r * s * f),
								b = u + h * (-r * o * d + i * s * f),
								x = v + h * (i * o * g + r * s * p),
								_ = m + h * (r * o * g - i * s * p);
							return ['C', y, b, x, _, v, m];
						}
						function o(t, e, i, o, a, c, h) {
							var l = Math.PI,
								u = (h * l) / 180,
								f = n.util.sin(u),
								d = n.util.cos(u),
								p = 0,
								g = 0;
							(i = Math.abs(i)), (o = Math.abs(o));
							var v = -d * t * 0.5 - f * e * 0.5,
								m = -d * e * 0.5 + f * t * 0.5,
								y = i * i,
								b = o * o,
								x = m * m,
								_ = v * v,
								w = y * b - y * x - b * _,
								C = 0;
							if (w < 0) {
								var S = Math.sqrt(1 - w / (y * b));
								(i *= S), (o *= S);
							} else C = (a === c ? -1 : 1) * Math.sqrt(w / (y * x + b * _));
							var T = (C * i * m) / o,
								O = (-C * o * v) / i,
								k = d * T - f * O + 0.5 * t,
								P = f * T + d * O + 0.5 * e,
								E = s(1, 0, (v - T) / i, (m - O) / o),
								M = s((v - T) / i, (m - O) / o, (-v - T) / i, (-m - O) / o);
							0 === c && M > 0 ? (M -= 2 * l) : 1 === c && M < 0 && (M += 2 * l);
							for (var j = Math.ceil(Math.abs((M / l) * 2)), D = [], A = M / j, F = ((8 / 3) * Math.sin(A / 4) * Math.sin(A / 4)) / Math.sin(A / 2), L = E + A, I = 0; I < j; I++)
								(D[I] = r(E, L, d, f, i, o, k, P, F, p, g)), (p = D[I][5]), (g = D[I][6]), (E = L), (L += A);
							return D;
						}
						function s(t, e, i, n) {
							var r = Math.atan2(e, t),
								o = Math.atan2(n, i);
							return o >= r ? o - r : 2 * Math.PI - (r - o);
						}
						function a(e, i, r, o, s, a, c, h) {
							var l;
							if (n.cachesBoundsOfCurve && ((l = t.call(arguments)), n.boundsOfCurveCache[l])) return n.boundsOfCurveCache[l];
							var u,
								f,
								d,
								p,
								g,
								v,
								m,
								y,
								b = Math.sqrt,
								x = Math.min,
								_ = Math.max,
								w = Math.abs,
								C = [],
								S = [[], []];
							(f = 6 * e - 12 * r + 6 * s), (u = -3 * e + 9 * r - 9 * s + 3 * c), (d = 3 * r - 3 * e);
							for (var T = 0; T < 2; ++T)
								if ((T > 0 && ((f = 6 * i - 12 * o + 6 * a), (u = -3 * i + 9 * o - 9 * a + 3 * h), (d = 3 * o - 3 * i)), w(u) < 1e-12)) {
									if (w(f) < 1e-12) continue;
									(p = -d / f), 0 < p && p < 1 && C.push(p);
								} else (m = f * f - 4 * d * u), m < 0 || ((y = b(m)), (g = (-f + y) / (2 * u)), 0 < g && g < 1 && C.push(g), (v = (-f - y) / (2 * u)), 0 < v && v < 1 && C.push(v));
							var O,
								k,
								P,
								E = C.length,
								M = E;
							while (E--)
								(p = C[E]),
									(P = 1 - p),
									(O = P * P * P * e + 3 * P * P * p * r + 3 * P * p * p * s + p * p * p * c),
									(S[0][E] = O),
									(k = P * P * P * i + 3 * P * P * p * o + 3 * P * p * p * a + p * p * p * h),
									(S[1][E] = k);
							(S[0][M] = e), (S[1][M] = i), (S[0][M + 1] = c), (S[1][M + 1] = h);
							var j = [
								{ x: x.apply(null, S[0]), y: x.apply(null, S[1]) },
								{ x: _.apply(null, S[0]), y: _.apply(null, S[1]) }
							];
							return n.cachesBoundsOfCurve && (n.boundsOfCurveCache[l] = j), j;
						}
						function c(t, e, i) {
							for (var n = i[1], r = i[2], s = i[3], a = i[4], c = i[5], h = i[6], l = i[7], u = o(h - t, l - e, n, r, a, c, s), f = 0, d = u.length; f < d; f++)
								(u[f][1] += t), (u[f][2] += e), (u[f][3] += t), (u[f][4] += e), (u[f][5] += t), (u[f][6] += e);
							return u;
						}
						function h(t) {
							var e,
								i,
								n,
								r,
								o,
								s,
								a = 0,
								h = 0,
								l = t.length,
								u = 0,
								f = 0,
								d = [];
							for (i = 0; i < l; ++i) {
								switch (((n = !1), (e = t[i].slice(0)), e[0])) {
									case 'l':
										(e[0] = 'L'), (e[1] += a), (e[2] += h);
									case 'L':
										(a = e[1]), (h = e[2]);
										break;
									case 'h':
										e[1] += a;
									case 'H':
										(e[0] = 'L'), (e[2] = h), (a = e[1]);
										break;
									case 'v':
										e[1] += h;
									case 'V':
										(e[0] = 'L'), (h = e[1]), (e[1] = a), (e[2] = h);
										break;
									case 'm':
										(e[0] = 'M'), (e[1] += a), (e[2] += h);
									case 'M':
										(a = e[1]), (h = e[2]), (u = e[1]), (f = e[2]);
										break;
									case 'c':
										(e[0] = 'C'), (e[1] += a), (e[2] += h), (e[3] += a), (e[4] += h), (e[5] += a), (e[6] += h);
									case 'C':
										(o = e[3]), (s = e[4]), (a = e[5]), (h = e[6]);
										break;
									case 's':
										(e[0] = 'S'), (e[1] += a), (e[2] += h), (e[3] += a), (e[4] += h);
									case 'S':
										'C' === r ? ((o = 2 * a - o), (s = 2 * h - s)) : ((o = a), (s = h)),
											(a = e[3]),
											(h = e[4]),
											(e[0] = 'C'),
											(e[5] = e[3]),
											(e[6] = e[4]),
											(e[3] = e[1]),
											(e[4] = e[2]),
											(e[1] = o),
											(e[2] = s),
											(o = e[3]),
											(s = e[4]);
										break;
									case 'q':
										(e[0] = 'Q'), (e[1] += a), (e[2] += h), (e[3] += a), (e[4] += h);
									case 'Q':
										(o = e[1]), (s = e[2]), (a = e[3]), (h = e[4]);
										break;
									case 't':
										(e[0] = 'T'), (e[1] += a), (e[2] += h);
									case 'T':
										'Q' === r ? ((o = 2 * a - o), (s = 2 * h - s)) : ((o = a), (s = h)), (e[0] = 'Q'), (a = e[1]), (h = e[2]), (e[1] = o), (e[2] = s), (e[3] = a), (e[4] = h);
										break;
									case 'a':
										(e[0] = 'A'), (e[6] += a), (e[7] += h);
									case 'A':
										(n = !0), (d = d.concat(c(a, h, e))), (a = e[6]), (h = e[7]);
										break;
									case 'z':
									case 'Z':
										(a = u), (h = f);
										break;
									default:
								}
								n || d.push(e), (r = e[0]);
							}
							return d;
						}
						function l(t, e, i, n) {
							return Math.sqrt((i - t) * (i - t) + (n - e) * (n - e));
						}
						function u(t) {
							return t * t * t;
						}
						function f(t) {
							return 3 * t * t * (1 - t);
						}
						function d(t) {
							return 3 * t * (1 - t) * (1 - t);
						}
						function p(t) {
							return (1 - t) * (1 - t) * (1 - t);
						}
						function g(t, e, i, n, r, o, s, a) {
							return function (c) {
								var h = u(c),
									l = f(c),
									g = d(c),
									v = p(c);
								return { x: s * h + r * l + i * g + t * v, y: a * h + o * l + n * g + e * v };
							};
						}
						function v(t, e, i, n, r, o, s, a) {
							return function (c) {
								var h = 1 - c,
									l = 3 * h * h * (i - t) + 6 * h * c * (r - i) + 3 * c * c * (s - r),
									u = 3 * h * h * (n - e) + 6 * h * c * (o - n) + 3 * c * c * (a - o);
								return Math.atan2(u, l);
							};
						}
						function m(t) {
							return t * t;
						}
						function y(t) {
							return 2 * t * (1 - t);
						}
						function b(t) {
							return (1 - t) * (1 - t);
						}
						function x(t, e, i, n, r, o) {
							return function (s) {
								var a = m(s),
									c = y(s),
									h = b(s);
								return { x: r * a + i * c + t * h, y: o * a + n * c + e * h };
							};
						}
						function _(t, e, i, n, r, o) {
							return function (s) {
								var a = 1 - s,
									c = 2 * a * (i - t) + 2 * s * (r - i),
									h = 2 * a * (n - e) + 2 * s * (o - n);
								return Math.atan2(h, c);
							};
						}
						function w(t, e, i) {
							var n,
								r,
								o = { x: e, y: i },
								s = 0;
							for (r = 1; r <= 100; r += 1) (n = t(r / 100)), (s += l(o.x, o.y, n.x, n.y)), (o = n);
							return s;
						}
						function C(t, e) {
							var i,
								n,
								r,
								o = 0,
								s = 0,
								a = t.iterator,
								c = { x: t.x, y: t.y },
								h = 0.01,
								u = t.angleFinder;
							while (s < e && h > 1e-4) (i = a(o)), (r = o), (n = l(c.x, c.y, i.x, i.y)), n + s > e ? ((o -= h), (h /= 2)) : ((c = i), (o += h), (s += n));
							return (i.angle = u(r)), i;
						}
						function S(t) {
							for (var e, i, n, r, o = 0, s = t.length, a = 0, c = 0, h = 0, u = 0, f = [], d = 0; d < s; d++) {
								switch (((e = t[d]), (n = { x: a, y: c, command: e[0] }), e[0])) {
									case 'M':
										(n.length = 0), (h = a = e[1]), (u = c = e[2]);
										break;
									case 'L':
										(n.length = l(a, c, e[1], e[2])), (a = e[1]), (c = e[2]);
										break;
									case 'C':
										(i = g(a, c, e[1], e[2], e[3], e[4], e[5], e[6])),
											(r = v(a, c, e[1], e[2], e[3], e[4], e[5], e[6])),
											(n.iterator = i),
											(n.angleFinder = r),
											(n.length = w(i, a, c)),
											(a = e[5]),
											(c = e[6]);
										break;
									case 'Q':
										(i = x(a, c, e[1], e[2], e[3], e[4])),
											(r = _(a, c, e[1], e[2], e[3], e[4])),
											(n.iterator = i),
											(n.angleFinder = r),
											(n.length = w(i, a, c)),
											(a = e[3]),
											(c = e[4]);
										break;
									case 'Z':
									case 'z':
										(n.destX = h), (n.destY = u), (n.length = l(a, c, h, u)), (a = h), (c = u);
										break;
								}
								(o += n.length), f.push(n);
							}
							return f.push({ length: o, x: a, y: c }), f;
						}
						function T(t, e, i) {
							i || (i = S(t));
							var r = 0;
							while (e - i[r].length > 0 && r < i.length - 2) (e -= i[r].length), r++;
							var o,
								s = i[r],
								a = e / s.length,
								c = s.command,
								h = t[r];
							switch (c) {
								case 'M':
									return { x: s.x, y: s.y, angle: 0 };
								case 'Z':
								case 'z':
									return (o = new n.Point(s.x, s.y).lerp(new n.Point(s.destX, s.destY), a)), (o.angle = Math.atan2(s.destY - s.y, s.destX - s.x)), o;
								case 'L':
									return (o = new n.Point(s.x, s.y).lerp(new n.Point(h[1], h[2]), a)), (o.angle = Math.atan2(h[2] - s.y, h[1] - s.x)), o;
								case 'C':
									return C(s, e);
								case 'Q':
									return C(s, e);
							}
						}
						function O(t) {
							var r,
								o,
								s,
								a,
								c,
								h = [],
								l = [],
								u = n.rePathCommand,
								f = '[-+]?(?:\\d*\\.\\d+|\\d+\\.?)(?:[eE][-+]?\\d+)?\\s*',
								d = '(' + f + ')' + n.commaWsp,
								p = '([01])' + n.commaWsp + '?',
								g = d + '?' + d + '?' + d + p + p + d + '?(' + f + ')',
								v = new RegExp(g, 'g');
							if (!t || !t.match) return h;
							c = t.match(/[mzlhvcsqta][^mzlhvcsqta]*/gi);
							for (var m, y = 0, b = c.length; y < b; y++) {
								(r = c[y]), (a = r.slice(1).trim()), (l.length = 0);
								var x = r.charAt(0);
								if (((m = [x]), 'a' === x.toLowerCase())) for (var _; (_ = v.exec(a)); ) for (var w = 1; w < _.length; w++) l.push(_[w]);
								else while ((s = u.exec(a))) l.push(s[0]);
								w = 0;
								for (var C = l.length; w < C; w++) (o = parseFloat(l[w])), isNaN(o) || m.push(o);
								var S = e[x.toLowerCase()],
									T = i[x] || x;
								if (m.length - 1 > S) for (var O = 1, k = m.length; O < k; O += S) h.push([x].concat(m.slice(O, O + S))), (x = T);
								else h.push(m);
							}
							return h;
						}
						function k(t, e) {
							var i,
								r = [],
								o = new n.Point(t[0].x, t[0].y),
								s = new n.Point(t[1].x, t[1].y),
								a = t.length,
								c = 1,
								h = 0,
								l = a > 2;
							for (
								e = e || 0, l && ((c = t[2].x < s.x ? -1 : t[2].x === s.x ? 0 : 1), (h = t[2].y < s.y ? -1 : t[2].y === s.y ? 0 : 1)), r.push(['M', o.x - c * e, o.y - h * e]), i = 1;
								i < a;
								i++
							) {
								if (!o.eq(s)) {
									var u = o.midPointFrom(s);
									r.push(['Q', o.x, o.y, u.x, u.y]);
								}
								(o = t[i]), i + 1 < t.length && (s = t[i + 1]);
							}
							return (
								l && ((c = o.x > t[i - 2].x ? 1 : o.x === t[i - 2].x ? 0 : -1), (h = o.y > t[i - 2].y ? 1 : o.y === t[i - 2].y ? 0 : -1)), r.push(['L', o.x + c * e, o.y + h * e]), r
							);
						}
						function P(t, e, i) {
							return (
								i && (e = n.util.multiplyTransformMatrices(e, [1, 0, 0, 1, -i.x, -i.y])),
								t.map(function (t) {
									for (var i = t.slice(0), r = {}, o = 1; o < t.length - 1; o += 2) (r.x = t[o]), (r.y = t[o + 1]), (r = n.util.transformPoint(r, e)), (i[o] = r.x), (i[o + 1] = r.y);
									return i;
								})
							);
						}
						(n.util.joinPath = function (t) {
							return t
								.map(function (t) {
									return t.join(' ');
								})
								.join(' ');
						}),
							(n.util.parsePath = O),
							(n.util.makePathSimpler = h),
							(n.util.getSmoothPathFromPoints = k),
							(n.util.getPathSegmentsInfo = S),
							(n.util.getBoundsOfCurve = a),
							(n.util.getPointOnPath = T),
							(n.util.transformPath = P);
					})(),
					(function () {
						var t = Array.prototype.slice;
						function e(e, i) {
							for (var n = t.call(arguments, 2), r = [], o = 0, s = e.length; o < s; o++) r[o] = n.length ? e[o][i].apply(e[o], n) : e[o][i].call(e[o]);
							return r;
						}
						function i(t, e) {
							return s(t, e, function (t, e) {
								return t >= e;
							});
						}
						function r(t, e) {
							return s(t, e, function (t, e) {
								return t < e;
							});
						}
						function o(t, e) {
							var i = t.length;
							while (i--) t[i] = e;
							return t;
						}
						function s(t, e, i) {
							if (t && 0 !== t.length) {
								var n = t.length - 1,
									r = e ? t[n][e] : t[n];
								if (e) while (n--) i(t[n][e], r) && (r = t[n][e]);
								else while (n--) i(t[n], r) && (r = t[n]);
								return r;
							}
						}
						n.util.array = { fill: o, invoke: e, min: r, max: i };
					})(),
					(function () {
						function t(e, i, r) {
							if (r)
								if (!n.isLikelyNode && i instanceof Element) e = i;
								else if (i instanceof Array) {
									e = [];
									for (var o = 0, s = i.length; o < s; o++) e[o] = t({}, i[o], r);
								} else if (i && 'object' === typeof i) for (var a in i) 'canvas' === a || 'group' === a ? (e[a] = null) : i.hasOwnProperty(a) && (e[a] = t({}, i[a], r));
								else e = i;
							else for (var a in i) e[a] = i[a];
							return e;
						}
						function e(e, i) {
							return t({}, e, i);
						}
						(n.util.object = { extend: t, clone: e }), n.util.object.extend(n.util, n.Observable);
					})(),
					(function () {
						function t(t) {
							return t.replace(/-+(.)?/g, function (t, e) {
								return e ? e.toUpperCase() : '';
							});
						}
						function e(t, e) {
							return t.charAt(0).toUpperCase() + (e ? t.slice(1) : t.slice(1).toLowerCase());
						}
						function i(t) {
							return t.replace(/&/g, '&amp;').replace(/"/g, '&quot;').replace(/'/g, '&apos;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
						}
						function r(t) {
							var e,
								i = 0,
								n = [];
							for (i = 0, e; i < t.length; i++) !1 !== (e = o(t, i)) && n.push(e);
							return n;
						}
						function o(t, e) {
							var i = t.charCodeAt(e);
							if (isNaN(i)) return '';
							if (i < 55296 || i > 57343) return t.charAt(e);
							if (55296 <= i && i <= 56319) {
								if (t.length <= e + 1) throw 'High surrogate without following low surrogate';
								var n = t.charCodeAt(e + 1);
								if (56320 > n || n > 57343) throw 'High surrogate without following low surrogate';
								return t.charAt(e) + t.charAt(e + 1);
							}
							if (0 === e) throw 'Low surrogate without preceding high surrogate';
							var r = t.charCodeAt(e - 1);
							if (55296 > r || r > 56319) throw 'Low surrogate without preceding high surrogate';
							return !1;
						}
						n.util.string = { camelize: t, capitalize: e, escapeXml: i, graphemeSplit: r };
					})(),
					(function () {
						var t = Array.prototype.slice,
							e = function () {},
							i = (function () {
								for (var t in { toString: 1 }) if ('toString' === t) return !1;
								return !0;
							})(),
							r = function (t, e, n) {
								for (var r in e)
									r in t.prototype && 'function' === typeof t.prototype[r] && (e[r] + '').indexOf('callSuper') > -1
										? (t.prototype[r] = (function (t) {
												return function () {
													var i = this.constructor.superclass;
													this.constructor.superclass = n;
													var r = e[t].apply(this, arguments);
													if (((this.constructor.superclass = i), 'initialize' !== t)) return r;
												};
										  })(r))
										: (t.prototype[r] = e[r]),
										i &&
											(e.toString !== Object.prototype.toString && (t.prototype.toString = e.toString),
											e.valueOf !== Object.prototype.valueOf && (t.prototype.valueOf = e.valueOf));
							};
						function o() {}
						function s(e) {
							var i = null,
								n = this;
							while (n.constructor.superclass) {
								var r = n.constructor.superclass.prototype[e];
								if (n[e] !== r) {
									i = r;
									break;
								}
								n = n.constructor.superclass.prototype;
							}
							return i
								? arguments.length > 1
									? i.apply(this, t.call(arguments, 1))
									: i.call(this)
								: console.log('tried to callSuper ' + e + ', method not found in prototype chain', this);
						}
						function a() {
							var i = null,
								n = t.call(arguments, 0);
							function a() {
								this.initialize.apply(this, arguments);
							}
							'function' === typeof n[0] && (i = n.shift()), (a.superclass = i), (a.subclasses = []), i && ((o.prototype = i.prototype), (a.prototype = new o()), i.subclasses.push(a));
							for (var c = 0, h = n.length; c < h; c++) r(a, n[c], i);
							return a.prototype.initialize || (a.prototype.initialize = e), (a.prototype.constructor = a), (a.prototype.callSuper = s), a;
						}
						n.util.createClass = a;
					})(),
					(function () {
						var t = !!n.document.createElement('div').attachEvent,
							e = ['touchstart', 'touchmove', 'touchend'];
						function i(t) {
							var e = t.changedTouches;
							return e && e[0] ? e[0] : t;
						}
						(n.util.addListener = function (e, i, n, r) {
							e && e.addEventListener(i, n, !t && r);
						}),
							(n.util.removeListener = function (e, i, n, r) {
								e && e.removeEventListener(i, n, !t && r);
							}),
							(n.util.getPointer = function (t) {
								var e = t.target,
									r = n.util.getScrollLeftTop(e),
									o = i(t);
								return { x: o.clientX + r.left, y: o.clientY + r.top };
							}),
							(n.util.isTouchEvent = function (t) {
								return e.indexOf(t.type) > -1 || 'touch' === t.pointerType;
							});
					})(),
					(function () {
						function t(t, e) {
							var i = t.style;
							if (!i) return t;
							if ('string' === typeof e) return (t.style.cssText += ';' + e), e.indexOf('opacity') > -1 ? s(t, e.match(/opacity:\s*(\d?\.?\d*)/)[1]) : t;
							for (var n in e)
								if ('opacity' === n) s(t, e[n]);
								else {
									var r = 'float' === n || 'cssFloat' === n ? ('undefined' === typeof i.styleFloat ? 'cssFloat' : 'styleFloat') : n;
									i.setProperty(r, e[n]);
								}
							return t;
						}
						var e = n.document.createElement('div'),
							i = 'string' === typeof e.style.opacity,
							r = 'string' === typeof e.style.filter,
							o = /alpha\s*\(\s*opacity\s*=\s*([^\)]+)\)/,
							s = function (t) {
								return t;
							};
						i
							? (s = function (t, e) {
									return (t.style.opacity = e), t;
							  })
							: r &&
							  (s = function (t, e) {
									var i = t.style;
									return (
										t.currentStyle && !t.currentStyle.hasLayout && (i.zoom = 1),
										o.test(i.filter)
											? ((e = e >= 0.9999 ? '' : 'alpha(opacity=' + 100 * e + ')'), (i.filter = i.filter.replace(o, e)))
											: (i.filter += ' alpha(opacity=' + 100 * e + ')'),
										t
									);
							  }),
							(n.util.setStyle = t);
					})(),
					(function () {
						var t = Array.prototype.slice;
						function e(t) {
							return 'string' === typeof t ? n.document.getElementById(t) : t;
						}
						var i,
							r,
							o = function (e) {
								return t.call(e, 0);
							};
						try {
							i = o(n.document.childNodes) instanceof Array;
						} catch (p) {}
						function s(t, e) {
							var i = n.document.createElement(t);
							for (var r in e) 'class' === r ? (i.className = e[r]) : 'for' === r ? (i.htmlFor = e[r]) : i.setAttribute(r, e[r]);
							return i;
						}
						function a(t, e) {
							t && -1 === (' ' + t.className + ' ').indexOf(' ' + e + ' ') && (t.className += (t.className ? ' ' : '') + e);
						}
						function c(t, e, i) {
							return 'string' === typeof e && (e = s(e, i)), t.parentNode && t.parentNode.replaceChild(e, t), e.appendChild(t), e;
						}
						function h(t) {
							var e = 0,
								i = 0,
								r = n.document.documentElement,
								o = n.document.body || { scrollLeft: 0, scrollTop: 0 };
							while (t && (t.parentNode || t.host))
								if (
									((t = t.parentNode || t.host),
									t === n.document ? ((e = o.scrollLeft || r.scrollLeft || 0), (i = o.scrollTop || r.scrollTop || 0)) : ((e += t.scrollLeft || 0), (i += t.scrollTop || 0)),
									1 === t.nodeType && 'fixed' === t.style.position)
								)
									break;
							return { left: e, top: i };
						}
						function l(t) {
							var e,
								i,
								n = t && t.ownerDocument,
								o = { left: 0, top: 0 },
								s = { left: 0, top: 0 },
								a = { borderLeftWidth: 'left', borderTopWidth: 'top', paddingLeft: 'left', paddingTop: 'top' };
							if (!n) return s;
							for (var c in a) s[a[c]] += parseInt(r(t, c), 10) || 0;
							return (
								(e = n.documentElement),
								'undefined' !== typeof t.getBoundingClientRect && (o = t.getBoundingClientRect()),
								(i = h(t)),
								{ left: o.left + i.left - (e.clientLeft || 0) + s.left, top: o.top + i.top - (e.clientTop || 0) + s.top }
							);
						}
						function u(t) {
							var e = n.jsdomImplForWrapper(t);
							return e._canvas || e._image;
						}
						function f(t) {
							if (n.isLikelyNode) {
								var e = n.jsdomImplForWrapper(t);
								e && ((e._image = null), (e._canvas = null), (e._currentSrc = null), (e._attributes = null), (e._classList = null));
							}
						}
						function d(t, e) {
							(t.imageSmoothingEnabled = t.imageSmoothingEnabled || t.webkitImageSmoothingEnabled || t.mozImageSmoothingEnabled || t.msImageSmoothingEnabled || t.oImageSmoothingEnabled),
								(t.imageSmoothingEnabled = e);
						}
						i ||
							(o = function (t) {
								var e = new Array(t.length),
									i = t.length;
								while (i--) e[i] = t[i];
								return e;
							}),
							(r =
								n.document.defaultView && n.document.defaultView.getComputedStyle
									? function (t, e) {
											var i = n.document.defaultView.getComputedStyle(t, null);
											return i ? i[e] : void 0;
									  }
									: function (t, e) {
											var i = t.style[e];
											return !i && t.currentStyle && (i = t.currentStyle[e]), i;
									  }),
							(function () {
								var t = n.document.documentElement.style,
									e =
										'userSelect' in t
											? 'userSelect'
											: 'MozUserSelect' in t
											? 'MozUserSelect'
											: 'WebkitUserSelect' in t
											? 'WebkitUserSelect'
											: 'KhtmlUserSelect' in t
											? 'KhtmlUserSelect'
											: '';
								function i(t) {
									return (
										'undefined' !== typeof t.onselectstart && (t.onselectstart = n.util.falseFunction),
										e ? (t.style[e] = 'none') : 'string' === typeof t.unselectable && (t.unselectable = 'on'),
										t
									);
								}
								function r(t) {
									return 'undefined' !== typeof t.onselectstart && (t.onselectstart = null), e ? (t.style[e] = '') : 'string' === typeof t.unselectable && (t.unselectable = ''), t;
								}
								(n.util.makeElementUnselectable = i), (n.util.makeElementSelectable = r);
							})(),
							(n.util.setImageSmoothing = d),
							(n.util.getById = e),
							(n.util.toArray = o),
							(n.util.addClass = a),
							(n.util.makeElement = s),
							(n.util.wrapElement = c),
							(n.util.getScrollLeftTop = h),
							(n.util.getElementOffset = l),
							(n.util.getNodeCanvas = u),
							(n.util.cleanUpJsdomNode = f);
					})(),
					(function () {
						function t(t, e) {
							return t + (/\?/.test(t) ? '&' : '?') + e;
						}
						function e() {}
						function i(i, r) {
							r || (r = {});
							var o = r.method ? r.method.toUpperCase() : 'GET',
								s = r.onComplete || function () {},
								a = new n.window.XMLHttpRequest(),
								c = r.body || r.parameters;
							return (
								(a.onreadystatechange = function () {
									4 === a.readyState && (s(a), (a.onreadystatechange = e));
								}),
								'GET' === o && ((c = null), 'string' === typeof r.parameters && (i = t(i, r.parameters))),
								a.open(o, i, !0),
								('POST' !== o && 'PUT' !== o) || a.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'),
								a.send(c),
								a
							);
						}
						n.util.request = i;
					})(),
					(n.log = console.log),
					(n.warn = console.warn),
					(function () {
						var t = n.util.object.extend,
							e = n.util.object.clone,
							i = [];
						function r() {
							return !1;
						}
						function o(t, e, i, n) {
							return -i * Math.cos((t / n) * (Math.PI / 2)) + i + e;
						}
						function s(i) {
							i || (i = {});
							var s,
								a = !1,
								c = function () {
									var t = n.runningAnimations.indexOf(s);
									return t > -1 && n.runningAnimations.splice(t, 1)[0];
								};
							return (
								(s = t(e(i), {
									cancel: function () {
										return (a = !0), c();
									},
									currentValue: 'startValue' in i ? i.startValue : 0,
									completionRate: 0,
									durationRate: 0
								})),
								n.runningAnimations.push(s),
								h(function (t) {
									var e,
										n = t || +new Date(),
										l = i.duration || 500,
										u = n + l,
										f = i.onChange || r,
										d = i.abort || r,
										p = i.onComplete || r,
										g = i.easing || o,
										v = 'startValue' in i && i.startValue.length > 0,
										m = 'startValue' in i ? i.startValue : 0,
										y = 'endValue' in i ? i.endValue : 100,
										b =
											i.byValue ||
											(v
												? m.map(function (t, e) {
														return y[e] - m[e];
												  })
												: y - m);
									i.onStart && i.onStart(),
										(function t(i) {
											e = i || +new Date();
											var r = e > u ? l : e - n,
												o = r / l,
												x = v
													? m.map(function (t, e) {
															return g(r, m[e], b[e], l);
													  })
													: g(r, m, b, l),
												_ = v ? Math.abs((x[0] - m[0]) / b[0]) : Math.abs((x - m) / b);
											if (((s.currentValue = v ? x.slice() : x), (s.completionRate = _), (s.durationRate = o), !a)) {
												if (!d(x, _, o))
													return e > u
														? ((s.currentValue = v ? y.slice() : y), (s.completionRate = 1), (s.durationRate = 1), f(v ? y.slice() : y, 1, 1), p(y, 1, 1), void c())
														: (f(x, _, o), void h(t));
												c();
											}
										})(n);
								}),
								s.cancel
							);
						}
						n.util.object.extend(i, {
							cancelAll: function () {
								var t = this.splice(0);
								return (
									t.forEach(function (t) {
										t.cancel();
									}),
									t
								);
							},
							cancelByCanvas: function (t) {
								if (!t) return [];
								var e = this.filter(function (e) {
									return 'object' === typeof e.target && e.target.canvas === t;
								});
								return (
									e.forEach(function (t) {
										t.cancel();
									}),
									e
								);
							},
							cancelByTarget: function (t) {
								var e = this.findAnimationsByTarget(t);
								return (
									e.forEach(function (t) {
										t.cancel();
									}),
									e
								);
							},
							findAnimationIndex: function (t) {
								return this.indexOf(this.findAnimation(t));
							},
							findAnimation: function (t) {
								return this.find(function (e) {
									return e.cancel === t;
								});
							},
							findAnimationsByTarget: function (t) {
								return t
									? this.filter(function (e) {
											return e.target === t;
									  })
									: [];
							}
						});
						var a =
								n.window.requestAnimationFrame ||
								n.window.webkitRequestAnimationFrame ||
								n.window.mozRequestAnimationFrame ||
								n.window.oRequestAnimationFrame ||
								n.window.msRequestAnimationFrame ||
								function (t) {
									return n.window.setTimeout(t, 1e3 / 60);
								},
							c = n.window.cancelAnimationFrame || n.window.clearTimeout;
						function h() {
							return a.apply(n.window, arguments);
						}
						function l() {
							return c.apply(n.window, arguments);
						}
						(n.util.animate = s), (n.util.requestAnimFrame = h), (n.util.cancelAnimFrame = l), (n.runningAnimations = i);
					})(),
					(function () {
						function t(t, e, i) {
							var n = 'rgba(' + parseInt(t[0] + i * (e[0] - t[0]), 10) + ',' + parseInt(t[1] + i * (e[1] - t[1]), 10) + ',' + parseInt(t[2] + i * (e[2] - t[2]), 10);
							return (n += ',' + (t && e ? parseFloat(t[3] + i * (e[3] - t[3])) : 1)), (n += ')'), n;
						}
						function e(e, i, r, o) {
							var s = new n.Color(e).getSource(),
								a = new n.Color(i).getSource(),
								c = o.onComplete,
								h = o.onChange;
							return (
								(o = o || {}),
								n.util.animate(
									n.util.object.extend(o, {
										duration: r || 500,
										startValue: s,
										endValue: a,
										byValue: a,
										easing: function (e, i, n, r) {
											var s = o.colorEasing ? o.colorEasing(e, r) : 1 - Math.cos((e / r) * (Math.PI / 2));
											return t(i, n, s);
										},
										onComplete: function (e, i, n) {
											if (c) return c(t(a, a, 0), i, n);
										},
										onChange: function (e, i, n) {
											if (h) {
												if (Array.isArray(e)) return h(t(e, e, 0), i, n);
												h(e, i, n);
											}
										}
									})
								)
							);
						}
						n.util.animateColor = e;
					})(),
					(function () {
						function t(t, e, i, n) {
							return (
								t < Math.abs(e) ? ((t = e), (n = i / 4)) : (n = 0 === e && 0 === t ? (i / (2 * Math.PI)) * Math.asin(1) : (i / (2 * Math.PI)) * Math.asin(e / t)),
								{ a: t, c: e, p: i, s: n }
							);
						}
						function e(t, e, i) {
							return t.a * Math.pow(2, 10 * (e -= 1)) * Math.sin(((e * i - t.s) * (2 * Math.PI)) / t.p);
						}
						function i(t, e, i, n) {
							return i * ((t = t / n - 1) * t * t + 1) + e;
						}
						function r(t, e, i, n) {
							return (t /= n / 2), t < 1 ? (i / 2) * t * t * t + e : (i / 2) * ((t -= 2) * t * t + 2) + e;
						}
						function o(t, e, i, n) {
							return i * (t /= n) * t * t * t + e;
						}
						function s(t, e, i, n) {
							return -i * ((t = t / n - 1) * t * t * t - 1) + e;
						}
						function a(t, e, i, n) {
							return (t /= n / 2), t < 1 ? (i / 2) * t * t * t * t + e : (-i / 2) * ((t -= 2) * t * t * t - 2) + e;
						}
						function c(t, e, i, n) {
							return i * (t /= n) * t * t * t * t + e;
						}
						function h(t, e, i, n) {
							return i * ((t = t / n - 1) * t * t * t * t + 1) + e;
						}
						function l(t, e, i, n) {
							return (t /= n / 2), t < 1 ? (i / 2) * t * t * t * t * t + e : (i / 2) * ((t -= 2) * t * t * t * t + 2) + e;
						}
						function u(t, e, i, n) {
							return -i * Math.cos((t / n) * (Math.PI / 2)) + i + e;
						}
						function f(t, e, i, n) {
							return i * Math.sin((t / n) * (Math.PI / 2)) + e;
						}
						function d(t, e, i, n) {
							return (-i / 2) * (Math.cos((Math.PI * t) / n) - 1) + e;
						}
						function p(t, e, i, n) {
							return 0 === t ? e : i * Math.pow(2, 10 * (t / n - 1)) + e;
						}
						function g(t, e, i, n) {
							return t === n ? e + i : i * (1 - Math.pow(2, (-10 * t) / n)) + e;
						}
						function v(t, e, i, n) {
							return 0 === t ? e : t === n ? e + i : ((t /= n / 2), t < 1 ? (i / 2) * Math.pow(2, 10 * (t - 1)) + e : (i / 2) * (2 - Math.pow(2, -10 * --t)) + e);
						}
						function m(t, e, i, n) {
							return -i * (Math.sqrt(1 - (t /= n) * t) - 1) + e;
						}
						function y(t, e, i, n) {
							return i * Math.sqrt(1 - (t = t / n - 1) * t) + e;
						}
						function b(t, e, i, n) {
							return (t /= n / 2), t < 1 ? (-i / 2) * (Math.sqrt(1 - t * t) - 1) + e : (i / 2) * (Math.sqrt(1 - (t -= 2) * t) + 1) + e;
						}
						function x(i, n, r, o) {
							var s = 1.70158,
								a = 0,
								c = r;
							if (0 === i) return n;
							if (((i /= o), 1 === i)) return n + r;
							a || (a = 0.3 * o);
							var h = t(c, r, a, s);
							return -e(h, i, o) + n;
						}
						function _(e, i, n, r) {
							var o = 1.70158,
								s = 0,
								a = n;
							if (0 === e) return i;
							if (((e /= r), 1 === e)) return i + n;
							s || (s = 0.3 * r);
							var c = t(a, n, s, o);
							return c.a * Math.pow(2, -10 * e) * Math.sin(((e * r - c.s) * (2 * Math.PI)) / c.p) + c.c + i;
						}
						function w(i, n, r, o) {
							var s = 1.70158,
								a = 0,
								c = r;
							if (0 === i) return n;
							if (((i /= o / 2), 2 === i)) return n + r;
							a || (a = o * (0.3 * 1.5));
							var h = t(c, r, a, s);
							return i < 1 ? -0.5 * e(h, i, o) + n : h.a * Math.pow(2, -10 * (i -= 1)) * Math.sin(((i * o - h.s) * (2 * Math.PI)) / h.p) * 0.5 + h.c + n;
						}
						function C(t, e, i, n, r) {
							return void 0 === r && (r = 1.70158), i * (t /= n) * t * ((r + 1) * t - r) + e;
						}
						function S(t, e, i, n, r) {
							return void 0 === r && (r = 1.70158), i * ((t = t / n - 1) * t * ((r + 1) * t + r) + 1) + e;
						}
						function T(t, e, i, n, r) {
							return (
								void 0 === r && (r = 1.70158),
								(t /= n / 2),
								t < 1 ? (i / 2) * (t * t * ((1 + (r *= 1.525)) * t - r)) + e : (i / 2) * ((t -= 2) * t * ((1 + (r *= 1.525)) * t + r) + 2) + e
							);
						}
						function O(t, e, i, n) {
							return i - k(n - t, 0, i, n) + e;
						}
						function k(t, e, i, n) {
							return (t /= n) < 1 / 2.75
								? i * (7.5625 * t * t) + e
								: t < 2 / 2.75
								? i * (7.5625 * (t -= 1.5 / 2.75) * t + 0.75) + e
								: t < 2.5 / 2.75
								? i * (7.5625 * (t -= 2.25 / 2.75) * t + 0.9375) + e
								: i * (7.5625 * (t -= 2.625 / 2.75) * t + 0.984375) + e;
						}
						function P(t, e, i, n) {
							return t < n / 2 ? 0.5 * O(2 * t, 0, i, n) + e : 0.5 * k(2 * t - n, 0, i, n) + 0.5 * i + e;
						}
						n.util.ease = {
							easeInQuad: function (t, e, i, n) {
								return i * (t /= n) * t + e;
							},
							easeOutQuad: function (t, e, i, n) {
								return -i * (t /= n) * (t - 2) + e;
							},
							easeInOutQuad: function (t, e, i, n) {
								return (t /= n / 2), t < 1 ? (i / 2) * t * t + e : (-i / 2) * (--t * (t - 2) - 1) + e;
							},
							easeInCubic: function (t, e, i, n) {
								return i * (t /= n) * t * t + e;
							},
							easeOutCubic: i,
							easeInOutCubic: r,
							easeInQuart: o,
							easeOutQuart: s,
							easeInOutQuart: a,
							easeInQuint: c,
							easeOutQuint: h,
							easeInOutQuint: l,
							easeInSine: u,
							easeOutSine: f,
							easeInOutSine: d,
							easeInExpo: p,
							easeOutExpo: g,
							easeInOutExpo: v,
							easeInCirc: m,
							easeOutCirc: y,
							easeInOutCirc: b,
							easeInElastic: x,
							easeOutElastic: _,
							easeInOutElastic: w,
							easeInBack: C,
							easeOutBack: S,
							easeInOutBack: T,
							easeInBounce: O,
							easeOutBounce: k,
							easeInOutBounce: P
						};
					})(),
					(function (t) {
						'use strict';
						var e = t.fabric || (t.fabric = {}),
							i = e.util.object.extend,
							n = e.util.object.clone,
							r = e.util.toFixed,
							o = e.util.parseUnit,
							s = e.util.multiplyTransformMatrices,
							a = ['path', 'circle', 'polygon', 'polyline', 'ellipse', 'rect', 'line', 'image', 'text'],
							c = ['symbol', 'image', 'marker', 'pattern', 'view', 'svg'],
							h = ['pattern', 'defs', 'symbol', 'metadata', 'clipPath', 'mask', 'desc'],
							l = ['symbol', 'g', 'a', 'svg', 'clipPath', 'defs'],
							u = {
								cx: 'left',
								x: 'left',
								r: 'radius',
								cy: 'top',
								y: 'top',
								display: 'visible',
								visibility: 'visible',
								transform: 'transformMatrix',
								'fill-opacity': 'fillOpacity',
								'fill-rule': 'fillRule',
								'font-family': 'fontFamily',
								'font-size': 'fontSize',
								'font-style': 'fontStyle',
								'font-weight': 'fontWeight',
								'letter-spacing': 'charSpacing',
								'paint-order': 'paintFirst',
								'stroke-dasharray': 'strokeDashArray',
								'stroke-dashoffset': 'strokeDashOffset',
								'stroke-linecap': 'strokeLineCap',
								'stroke-linejoin': 'strokeLineJoin',
								'stroke-miterlimit': 'strokeMiterLimit',
								'stroke-opacity': 'strokeOpacity',
								'stroke-width': 'strokeWidth',
								'text-decoration': 'textDecoration',
								'text-anchor': 'textAnchor',
								opacity: 'opacity',
								'clip-path': 'clipPath',
								'clip-rule': 'clipRule',
								'vector-effect': 'strokeUniform',
								'image-rendering': 'imageSmoothing'
							},
							f = { stroke: 'strokeOpacity', fill: 'fillOpacity' },
							d = 'font-size',
							p = 'clip-path';
						function g(t) {
							return t in u ? u[t] : t;
						}
						function v(t, i, n, r) {
							var a,
								c = Array.isArray(i);
							if (('fill' !== t && 'stroke' !== t) || 'none' !== i) {
								if ('strokeUniform' === t) return 'non-scaling-stroke' === i;
								if ('strokeDashArray' === t) i = 'none' === i ? null : i.replace(/,/g, ' ').split(/\s+/).map(parseFloat);
								else if ('transformMatrix' === t) i = n && n.transformMatrix ? s(n.transformMatrix, e.parseTransformAttribute(i)) : e.parseTransformAttribute(i);
								else if ('visible' === t) (i = 'none' !== i && 'hidden' !== i), n && !1 === n.visible && (i = !1);
								else if ('opacity' === t) (i = parseFloat(i)), n && 'undefined' !== typeof n.opacity && (i *= n.opacity);
								else if ('textAnchor' === t) i = 'start' === i ? 'left' : 'end' === i ? 'right' : 'center';
								else if ('charSpacing' === t) a = (o(i, r) / r) * 1e3;
								else if ('paintFirst' === t) {
									var h = i.indexOf('fill'),
										l = i.indexOf('stroke');
									i = 'fill';
									((h > -1 && l > -1 && l < h) || (-1 === h && l > -1)) && (i = 'stroke');
								} else {
									if ('href' === t || 'xlink:href' === t || 'font' === t) return i;
									if ('imageSmoothing' === t) return 'optimizeQuality' === i;
									a = c ? i.map(o) : o(i, r);
								}
							} else i = '';
							return !c && isNaN(a) ? i : a;
						}
						function m(t) {
							return new RegExp('^(' + t.join('|') + ')\\b', 'i');
						}
						function y(t) {
							for (var i in f)
								if ('undefined' !== typeof t[f[i]] && '' !== t[i]) {
									if ('undefined' === typeof t[i]) {
										if (!e.Object.prototype[i]) continue;
										t[i] = e.Object.prototype[i];
									}
									if (0 !== t[i].indexOf('url(')) {
										var n = new e.Color(t[i]);
										t[i] = n.setAlpha(r(n.getAlpha() * t[f[i]], 2)).toRgba();
									}
								}
							return t;
						}
						function b(t, e) {
							var i,
								n,
								r,
								o,
								s = [];
							for (r = 0, o = e.length; r < o; r++) (i = e[r]), (n = t.getElementsByTagName(i)), (s = s.concat(Array.prototype.slice.call(n)));
							return s;
						}
						function x(t, e) {
							var i, n;
							t.replace(/;\s*$/, '')
								.split(';')
								.forEach(function (t) {
									var r = t.split(':');
									(i = r[0].trim().toLowerCase()), (n = r[1].trim()), (e[i] = n);
								});
						}
						function _(t, e) {
							var i, n;
							for (var r in t) 'undefined' !== typeof t[r] && ((i = r.toLowerCase()), (n = t[r]), (e[i] = n));
						}
						function w(t, i) {
							var n = {};
							for (var r in e.cssRules[i]) if (C(t, r.split(' '))) for (var o in e.cssRules[i][r]) n[o] = e.cssRules[i][r][o];
							return n;
						}
						function C(t, e) {
							var i,
								n = !0;
							return (i = T(t, e.pop())), i && e.length && (n = S(t, e)), i && n && 0 === e.length;
						}
						function S(t, e) {
							var i,
								n = !0;
							while (t.parentNode && 1 === t.parentNode.nodeType && e.length) n && (i = e.pop()), (t = t.parentNode), (n = T(t, i));
							return 0 === e.length;
						}
						function T(t, e) {
							var i,
								n,
								r = t.nodeName,
								o = t.getAttribute('class'),
								s = t.getAttribute('id');
							if (((i = new RegExp('^' + r, 'i')), (e = e.replace(i, '')), s && e.length && ((i = new RegExp('#' + s + '(?![a-zA-Z\\-]+)', 'i')), (e = e.replace(i, ''))), o && e.length))
								for (o = o.split(' '), n = o.length; n--; ) (i = new RegExp('\\.' + o[n] + '(?![a-zA-Z\\-]+)', 'i')), (e = e.replace(i, ''));
							return 0 === e.length;
						}
						function O(t, e) {
							var i;
							if ((t.getElementById && (i = t.getElementById(e)), i)) return i;
							var n,
								r,
								o,
								s = t.getElementsByTagName('*');
							for (r = 0, o = s.length; r < o; r++) if (((n = s[r]), e === n.getAttribute('id'))) return n;
						}
						function k(t) {
							var i = b(t, ['use', 'svg:use']),
								n = 0;
							while (i.length && n < i.length) {
								var r = i[n],
									o = r.getAttribute('xlink:href') || r.getAttribute('href');
								if (null === o) return;
								var s,
									a,
									c,
									h,
									l,
									u = o.slice(1),
									f = r.getAttribute('x') || 0,
									d = r.getAttribute('y') || 0,
									p = O(t, u).cloneNode(!0),
									g = (p.getAttribute('transform') || '') + ' translate(' + f + ', ' + d + ')',
									v = i.length,
									m = e.svgNS;
								if ((E(p), /^svg$/i.test(p.nodeName))) {
									var y = p.ownerDocument.createElementNS(m, 'g');
									for (c = 0, h = p.attributes, l = h.length; c < l; c++) (a = h.item(c)), y.setAttributeNS(m, a.nodeName, a.nodeValue);
									while (p.firstChild) y.appendChild(p.firstChild);
									p = y;
								}
								for (c = 0, h = r.attributes, l = h.length; c < l; c++)
									(a = h.item(c)),
										'x' !== a.nodeName &&
											'y' !== a.nodeName &&
											'xlink:href' !== a.nodeName &&
											'href' !== a.nodeName &&
											('transform' === a.nodeName ? (g = a.nodeValue + ' ' + g) : p.setAttribute(a.nodeName, a.nodeValue));
								p.setAttribute('transform', g), p.setAttribute('instantiated_by_use', '1'), p.removeAttribute('id'), (s = r.parentNode), s.replaceChild(p, r), i.length === v && n++;
							}
						}
						(e.svgValidTagNamesRegEx = m(a)),
							(e.svgViewBoxElementsRegEx = m(c)),
							(e.svgInvalidAncestorsRegEx = m(h)),
							(e.svgValidParentsRegEx = m(l)),
							(e.cssRules = {}),
							(e.gradientDefs = {}),
							(e.clipPaths = {}),
							(e.parseTransformAttribute = (function () {
								function t(t, i) {
									var n = e.util.cos(i[0]),
										r = e.util.sin(i[0]),
										o = 0,
										s = 0;
									3 === i.length && ((o = i[1]), (s = i[2])), (t[0] = n), (t[1] = r), (t[2] = -r), (t[3] = n), (t[4] = o - (n * o - r * s)), (t[5] = s - (r * o + n * s));
								}
								function i(t, e) {
									var i = e[0],
										n = 2 === e.length ? e[1] : e[0];
									(t[0] = i), (t[3] = n);
								}
								function n(t, i, n) {
									t[n] = Math.tan(e.util.degreesToRadians(i[0]));
								}
								function r(t, e) {
									(t[4] = e[0]), 2 === e.length && (t[5] = e[1]);
								}
								var o = e.iMatrix,
									s = e.reNum,
									a = e.commaWsp,
									c = '(?:(skewX)\\s*\\(\\s*(' + s + ')\\s*\\))',
									h = '(?:(skewY)\\s*\\(\\s*(' + s + ')\\s*\\))',
									l = '(?:(rotate)\\s*\\(\\s*(' + s + ')(?:' + a + '(' + s + ')' + a + '(' + s + '))?\\s*\\))',
									u = '(?:(scale)\\s*\\(\\s*(' + s + ')(?:' + a + '(' + s + '))?\\s*\\))',
									f = '(?:(translate)\\s*\\(\\s*(' + s + ')(?:' + a + '(' + s + '))?\\s*\\))',
									d = '(?:(matrix)\\s*\\(\\s*(' + s + ')' + a + '(' + s + ')' + a + '(' + s + ')' + a + '(' + s + ')' + a + '(' + s + ')' + a + '(' + s + ')\\s*\\))',
									p = '(?:' + d + '|' + f + '|' + u + '|' + l + '|' + c + '|' + h + ')',
									g = '(?:' + p + '(?:' + a + '*' + p + ')*)',
									v = '^\\s*(?:' + g + '?)\\s*$',
									m = new RegExp(v),
									y = new RegExp(p, 'g');
								return function (s) {
									var a = o.concat(),
										c = [];
									if (!s || (s && !m.test(s))) return a;
									s.replace(y, function (s) {
										var h = new RegExp(p).exec(s).filter(function (t) {
												return !!t;
											}),
											l = h[1],
											u = h.slice(2).map(parseFloat);
										switch (l) {
											case 'translate':
												r(a, u);
												break;
											case 'rotate':
												(u[0] = e.util.degreesToRadians(u[0])), t(a, u);
												break;
											case 'scale':
												i(a, u);
												break;
											case 'skewX':
												n(a, u, 2);
												break;
											case 'skewY':
												n(a, u, 1);
												break;
											case 'matrix':
												a = u;
												break;
										}
										c.push(a.concat()), (a = o.concat());
									});
									var h = c[0];
									while (c.length > 1) c.shift(), (h = e.util.multiplyTransformMatrices(h, c[0]));
									return h;
								};
							})());
						var P = new RegExp('^\\s*(' + e.reNum + '+)\\s*,?\\s*(' + e.reNum + '+)\\s*,?\\s*(' + e.reNum + '+)\\s*,?\\s*(' + e.reNum + '+)\\s*$');
						function E(t) {
							if (!e.svgViewBoxElementsRegEx.test(t.nodeName)) return {};
							var i,
								n,
								r,
								s,
								a = t.getAttribute('viewBox'),
								c = 1,
								h = 1,
								l = 0,
								u = 0,
								f = t.getAttribute('width'),
								d = t.getAttribute('height'),
								p = t.getAttribute('x') || 0,
								g = t.getAttribute('y') || 0,
								v = t.getAttribute('preserveAspectRatio') || '',
								m = !a || !(a = a.match(P)),
								y = !f || !d || '100%' === f || '100%' === d,
								b = m && y,
								x = {},
								_ = '',
								w = 0,
								C = 0;
							if (
								((x.width = 0),
								(x.height = 0),
								(x.toBeParsed = b),
								m &&
									(p || g) &&
									t.parentNode &&
									'#document' !== t.parentNode.nodeName &&
									((_ = ' translate(' + o(p) + ' ' + o(g) + ') '),
									(r = (t.getAttribute('transform') || '') + _),
									t.setAttribute('transform', r),
									t.removeAttribute('x'),
									t.removeAttribute('y')),
								b)
							)
								return x;
							if (m) return (x.width = o(f)), (x.height = o(d)), x;
							if (
								((l = -parseFloat(a[1])),
								(u = -parseFloat(a[2])),
								(i = parseFloat(a[3])),
								(n = parseFloat(a[4])),
								(x.minX = l),
								(x.minY = u),
								(x.viewBoxWidth = i),
								(x.viewBoxHeight = n),
								y ? ((x.width = i), (x.height = n)) : ((x.width = o(f)), (x.height = o(d)), (c = x.width / i), (h = x.height / n)),
								(v = e.util.parsePreserveAspectRatioAttribute(v)),
								'none' !== v.alignX &&
									('meet' === v.meetOrSlice && (h = c = c > h ? h : c),
									'slice' === v.meetOrSlice && (h = c = c > h ? c : h),
									(w = x.width - i * c),
									(C = x.height - n * c),
									'Mid' === v.alignX && (w /= 2),
									'Mid' === v.alignY && (C /= 2),
									'Min' === v.alignX && (w = 0),
									'Min' === v.alignY && (C = 0)),
								1 === c && 1 === h && 0 === l && 0 === u && 0 === p && 0 === g)
							)
								return x;
							if (
								((p || g) && '#document' !== t.parentNode.nodeName && (_ = ' translate(' + o(p) + ' ' + o(g) + ') '),
								(r = _ + ' matrix(' + c + ' 0 0 ' + h + ' ' + (l * c + w) + ' ' + (u * h + C) + ') '),
								'svg' === t.nodeName)
							) {
								s = t.ownerDocument.createElementNS(e.svgNS, 'g');
								while (t.firstChild) s.appendChild(t.firstChild);
								t.appendChild(s);
							} else (s = t), s.removeAttribute('x'), s.removeAttribute('y'), (r = s.getAttribute('transform') + r);
							return s.setAttribute('transform', r), x;
						}
						function M(t, e) {
							while (t && (t = t.parentNode)) if (t.nodeName && e.test(t.nodeName.replace('svg:', '')) && !t.getAttribute('instantiated_by_use')) return !0;
							return !1;
						}
						function j(t, e) {
							var i = ['gradientTransform', 'x1', 'x2', 'y1', 'y2', 'gradientUnits', 'cx', 'cy', 'r', 'fx', 'fy'],
								n = 'xlink:href',
								r = e.getAttribute(n).slice(1),
								o = O(t, r);
							if (
								(o && o.getAttribute(n) && j(t, o),
								i.forEach(function (t) {
									o && !e.hasAttribute(t) && o.hasAttribute(t) && e.setAttribute(t, o.getAttribute(t));
								}),
								!e.children.length)
							) {
								var s = o.cloneNode(!0);
								while (s.firstChild) e.appendChild(s.firstChild);
							}
							e.removeAttribute(n);
						}
						e.parseSVGDocument = function (t, i, r, o) {
							if (t) {
								k(t);
								var s,
									a,
									c = e.Object.__uid++,
									h = E(t),
									l = e.util.toArray(t.getElementsByTagName('*'));
								if (((h.crossOrigin = o && o.crossOrigin), (h.svgUid = c), 0 === l.length && e.isLikelyNode)) {
									l = t.selectNodes('//*[name(.)!="svg"]');
									var u = [];
									for (s = 0, a = l.length; s < a; s++) u[s] = l[s];
									l = u;
								}
								var f = l.filter(function (t) {
									return E(t), e.svgValidTagNamesRegEx.test(t.nodeName.replace('svg:', '')) && !M(t, e.svgInvalidAncestorsRegEx);
								});
								if (!f || (f && !f.length)) i && i([], {});
								else {
									var d = {};
									l
										.filter(function (t) {
											return 'clipPath' === t.nodeName.replace('svg:', '');
										})
										.forEach(function (t) {
											var i = t.getAttribute('id');
											d[i] = e.util.toArray(t.getElementsByTagName('*')).filter(function (t) {
												return e.svgValidTagNamesRegEx.test(t.nodeName.replace('svg:', ''));
											});
										}),
										(e.gradientDefs[c] = e.getGradientDefs(t)),
										(e.cssRules[c] = e.getCSSRules(t)),
										(e.clipPaths[c] = d),
										e.parseElements(
											f,
											function (t, n) {
												i && (i(t, h, n, l), delete e.gradientDefs[c], delete e.cssRules[c], delete e.clipPaths[c]);
											},
											n(h),
											r,
											o
										);
								}
							}
						};
						var D = new RegExp(
							'(normal|italic)?\\s*(normal|small-caps)?\\s*(normal|bold|bolder|lighter|100|200|300|400|500|600|700|800|900)?\\s*(' +
								e.reNum +
								'(?:px|cm|mm|em|pt|pc|in)*)(?:\\/(normal|' +
								e.reNum +
								'))?\\s+(.*)'
						);
						i(e, {
							parseFontDeclaration: function (t, e) {
								var i = t.match(D);
								if (i) {
									var n = i[1],
										r = i[3],
										s = i[4],
										a = i[5],
										c = i[6];
									n && (e.fontStyle = n),
										r && (e.fontWeight = isNaN(parseFloat(r)) ? r : parseFloat(r)),
										s && (e.fontSize = o(s)),
										c && (e.fontFamily = c),
										a && (e.lineHeight = 'normal' === a ? 1 : a);
								}
							},
							getGradientDefs: function (t) {
								var e,
									i = ['linearGradient', 'radialGradient', 'svg:linearGradient', 'svg:radialGradient'],
									n = b(t, i),
									r = 0,
									o = {};
								r = n.length;
								while (r--) (e = n[r]), e.getAttribute('xlink:href') && j(t, e), (o[e.getAttribute('id')] = e);
								return o;
							},
							parseAttributes: function (t, n, r) {
								if (t) {
									var s,
										a,
										c,
										h = {};
									'undefined' === typeof r && (r = t.getAttribute('svgUid')),
										t.parentNode && e.svgValidParentsRegEx.test(t.parentNode.nodeName) && (h = e.parseAttributes(t.parentNode, n, r));
									var l = n.reduce(function (e, i) {
											return (s = t.getAttribute(i)), s && (e[i] = s), e;
										}, {}),
										u = i(w(t, r), e.parseStyleAttribute(t));
									(l = i(l, u)), u[p] && t.setAttribute(p, u[p]), (a = c = h.fontSize || e.Text.DEFAULT_SVG_FONT_SIZE), l[d] && (l[d] = a = o(l[d], c));
									var f,
										m,
										b = {};
									for (var x in l) (f = g(x)), (m = v(f, l[x], h, a)), (b[f] = m);
									b && b.font && e.parseFontDeclaration(b.font, b);
									var _ = i(h, b);
									return e.svgValidParentsRegEx.test(t.nodeName) ? _ : y(_);
								}
							},
							parseElements: function (t, i, n, r, o) {
								new e.ElementsParser(t, i, n, r, o).parse();
							},
							parseStyleAttribute: function (t) {
								var e = {},
									i = t.getAttribute('style');
								return i ? ('string' === typeof i ? x(i, e) : _(i, e), e) : e;
							},
							parsePointsAttribute: function (t) {
								if (!t) return null;
								(t = t.replace(/,/g, ' ').trim()), (t = t.split(/\s+/));
								var e,
									i,
									n = [];
								for (e = 0, i = t.length; e < i; e += 2) n.push({ x: parseFloat(t[e]), y: parseFloat(t[e + 1]) });
								return n;
							},
							getCSSRules: function (t) {
								var i,
									n,
									r,
									o = t.getElementsByTagName('style'),
									s = {};
								for (i = 0, n = o.length; i < n; i++) {
									var a = o[i].textContent;
									(a = a.replace(/\/\*[\s\S]*?\*\//g, '')),
										'' !== a.trim() &&
											((r = a.split('}')),
											(r = r.filter(function (t) {
												return t.trim();
											})),
											r.forEach(function (t) {
												var r = t.split('{'),
													o = {},
													a = r[1].trim(),
													c = a.split(';').filter(function (t) {
														return t.trim();
													});
												for (i = 0, n = c.length; i < n; i++) {
													var h = c[i].split(':'),
														l = h[0].trim(),
														u = h[1].trim();
													o[l] = u;
												}
												(t = r[0].trim()),
													t.split(',').forEach(function (t) {
														(t = t.replace(/^svg/i, '').trim()), '' !== t && (s[t] ? e.util.object.extend(s[t], o) : (s[t] = e.util.object.clone(o)));
													});
											}));
								}
								return s;
							},
							loadSVGFromURL: function (t, i, n, r) {
								function o(t) {
									var o = t.responseXML;
									if (!o || !o.documentElement) return i && i(null), !1;
									e.parseSVGDocument(
										o.documentElement,
										function (t, e, n, r) {
											i && i(t, e, n, r);
										},
										n,
										r
									);
								}
								(t = t.replace(/^\n\s*/, '').trim()), new e.util.request(t, { method: 'get', onComplete: o });
							},
							loadSVGFromString: function (t, i, n, r) {
								var o = new e.window.DOMParser(),
									s = o.parseFromString(t.trim(), 'text/xml');
								e.parseSVGDocument(
									s.documentElement,
									function (t, e, n, r) {
										i(t, e, n, r);
									},
									n,
									r
								);
							}
						});
					})(e),
					(n.ElementsParser = function (t, e, i, n, r, o) {
						(this.elements = t),
							(this.callback = e),
							(this.options = i),
							(this.reviver = n),
							(this.svgUid = (i && i.svgUid) || 0),
							(this.parsingOptions = r),
							(this.regexUrl = /^url\(['"]?#([^'"]+)['"]?\)/g),
							(this.doc = o);
					}),
					(function (t) {
						(t.parse = function () {
							(this.instances = new Array(this.elements.length)), (this.numElements = this.elements.length), this.createObjects();
						}),
							(t.createObjects = function () {
								var t = this;
								this.elements.forEach(function (e, i) {
									e.setAttribute('svgUid', t.svgUid), t.createObject(e, i);
								});
							}),
							(t.findTag = function (t) {
								return n[n.util.string.capitalize(t.tagName.replace('svg:', ''))];
							}),
							(t.createObject = function (t, e) {
								var i = this.findTag(t);
								if (i && i.fromElement)
									try {
										i.fromElement(t, this.createCallback(e, t), this.options);
									} catch (r) {
										n.log(r);
									}
								else this.checkIfDone();
							}),
							(t.createCallback = function (t, e) {
								var i = this;
								return function (r) {
									var o;
									i.resolveGradient(r, e, 'fill'),
										i.resolveGradient(r, e, 'stroke'),
										r instanceof n.Image && r._originalElement && (o = r.parsePreserveAspectRatioAttribute(e)),
										r._removeTransformMatrix(o),
										i.resolveClipPath(r, e),
										i.reviver && i.reviver(e, r),
										(i.instances[t] = r),
										i.checkIfDone();
								};
							}),
							(t.extractPropertyDefinition = function (t, e, i) {
								var r = t[e],
									o = this.regexUrl;
								if (o.test(r)) {
									o.lastIndex = 0;
									var s = o.exec(r)[1];
									return (o.lastIndex = 0), n[i][this.svgUid][s];
								}
							}),
							(t.resolveGradient = function (t, e, i) {
								var r = this.extractPropertyDefinition(t, i, 'gradientDefs');
								if (r) {
									var o = e.getAttribute(i + '-opacity'),
										s = n.Gradient.fromElement(r, t, o, this.options);
									t.set(i, s);
								}
							}),
							(t.createClipPathCallback = function (t, e) {
								return function (t) {
									t._removeTransformMatrix(), (t.fillRule = t.clipRule), e.push(t);
								};
							}),
							(t.resolveClipPath = function (t, e) {
								var i,
									r,
									o,
									s,
									a,
									c = this.extractPropertyDefinition(t, 'clipPath', 'clipPaths');
								if (c) {
									(s = []), (o = n.util.invertTransform(t.calcTransformMatrix()));
									var h = c[0].parentNode,
										l = e;
									while (l.parentNode && l.getAttribute('clip-path') !== t.clipPath) l = l.parentNode;
									l.parentNode.appendChild(h);
									for (var u = 0; u < c.length; u++) (i = c[u]), (r = this.findTag(i)), r.fromElement(i, this.createClipPathCallback(t, s), this.options);
									(c = 1 === s.length ? s[0] : new n.Group(s)), (a = n.util.multiplyTransformMatrices(o, c.calcTransformMatrix())), c.clipPath && this.resolveClipPath(c, l);
									var f = n.util.qrDecompose(a);
									(c.flipX = !1),
										(c.flipY = !1),
										c.set('scaleX', f.scaleX),
										c.set('scaleY', f.scaleY),
										(c.angle = f.angle),
										(c.skewX = f.skewX),
										(c.skewY = 0),
										c.setPositionByOrigin({ x: f.translateX, y: f.translateY }, 'center', 'center'),
										(t.clipPath = c);
								} else delete t.clipPath;
							}),
							(t.checkIfDone = function () {
								0 === --this.numElements &&
									((this.instances = this.instances.filter(function (t) {
										return null != t;
									})),
									this.callback(this.instances, this.elements));
							});
					})(n.ElementsParser.prototype),
					(function (t) {
						'use strict';
						var e = t.fabric || (t.fabric = {});
						function i(t, e) {
							(this.x = t), (this.y = e);
						}
						e.Point
							? e.warn('fabric.Point is already defined')
							: ((e.Point = i),
							  (i.prototype = {
									type: 'point',
									constructor: i,
									add: function (t) {
										return new i(this.x + t.x, this.y + t.y);
									},
									addEquals: function (t) {
										return (this.x += t.x), (this.y += t.y), this;
									},
									scalarAdd: function (t) {
										return new i(this.x + t, this.y + t);
									},
									scalarAddEquals: function (t) {
										return (this.x += t), (this.y += t), this;
									},
									subtract: function (t) {
										return new i(this.x - t.x, this.y - t.y);
									},
									subtractEquals: function (t) {
										return (this.x -= t.x), (this.y -= t.y), this;
									},
									scalarSubtract: function (t) {
										return new i(this.x - t, this.y - t);
									},
									scalarSubtractEquals: function (t) {
										return (this.x -= t), (this.y -= t), this;
									},
									multiply: function (t) {
										return new i(this.x * t, this.y * t);
									},
									multiplyEquals: function (t) {
										return (this.x *= t), (this.y *= t), this;
									},
									divide: function (t) {
										return new i(this.x / t, this.y / t);
									},
									divideEquals: function (t) {
										return (this.x /= t), (this.y /= t), this;
									},
									eq: function (t) {
										return this.x === t.x && this.y === t.y;
									},
									lt: function (t) {
										return this.x < t.x && this.y < t.y;
									},
									lte: function (t) {
										return this.x <= t.x && this.y <= t.y;
									},
									gt: function (t) {
										return this.x > t.x && this.y > t.y;
									},
									gte: function (t) {
										return this.x >= t.x && this.y >= t.y;
									},
									lerp: function (t, e) {
										return 'undefined' === typeof e && (e = 0.5), (e = Math.max(Math.min(1, e), 0)), new i(this.x + (t.x - this.x) * e, this.y + (t.y - this.y) * e);
									},
									distanceFrom: function (t) {
										var e = this.x - t.x,
											i = this.y - t.y;
										return Math.sqrt(e * e + i * i);
									},
									midPointFrom: function (t) {
										return this.lerp(t);
									},
									min: function (t) {
										return new i(Math.min(this.x, t.x), Math.min(this.y, t.y));
									},
									max: function (t) {
										return new i(Math.max(this.x, t.x), Math.max(this.y, t.y));
									},
									toString: function () {
										return this.x + ',' + this.y;
									},
									setXY: function (t, e) {
										return (this.x = t), (this.y = e), this;
									},
									setX: function (t) {
										return (this.x = t), this;
									},
									setY: function (t) {
										return (this.y = t), this;
									},
									setFromPoint: function (t) {
										return (this.x = t.x), (this.y = t.y), this;
									},
									swap: function (t) {
										var e = this.x,
											i = this.y;
										(this.x = t.x), (this.y = t.y), (t.x = e), (t.y = i);
									},
									clone: function () {
										return new i(this.x, this.y);
									}
							  }));
					})(e),
					(function (t) {
						'use strict';
						var e = t.fabric || (t.fabric = {});
						function i(t) {
							(this.status = t), (this.points = []);
						}
						e.Intersection
							? e.warn('fabric.Intersection is already defined')
							: ((e.Intersection = i),
							  (e.Intersection.prototype = {
									constructor: i,
									appendPoint: function (t) {
										return this.points.push(t), this;
									},
									appendPoints: function (t) {
										return (this.points = this.points.concat(t)), this;
									}
							  }),
							  (e.Intersection.intersectLineLine = function (t, n, r, o) {
									var s,
										a = (o.x - r.x) * (t.y - r.y) - (o.y - r.y) * (t.x - r.x),
										c = (n.x - t.x) * (t.y - r.y) - (n.y - t.y) * (t.x - r.x),
										h = (o.y - r.y) * (n.x - t.x) - (o.x - r.x) * (n.y - t.y);
									if (0 !== h) {
										var l = a / h,
											u = c / h;
										0 <= l && l <= 1 && 0 <= u && u <= 1 ? ((s = new i('Intersection')), s.appendPoint(new e.Point(t.x + l * (n.x - t.x), t.y + l * (n.y - t.y)))) : (s = new i());
									} else s = new i(0 === a || 0 === c ? 'Coincident' : 'Parallel');
									return s;
							  }),
							  (e.Intersection.intersectLinePolygon = function (t, e, n) {
									var r,
										o,
										s,
										a,
										c = new i(),
										h = n.length;
									for (a = 0; a < h; a++) (r = n[a]), (o = n[(a + 1) % h]), (s = i.intersectLineLine(t, e, r, o)), c.appendPoints(s.points);
									return c.points.length > 0 && (c.status = 'Intersection'), c;
							  }),
							  (e.Intersection.intersectPolygonPolygon = function (t, e) {
									var n,
										r = new i(),
										o = t.length;
									for (n = 0; n < o; n++) {
										var s = t[n],
											a = t[(n + 1) % o],
											c = i.intersectLinePolygon(s, a, e);
										r.appendPoints(c.points);
									}
									return r.points.length > 0 && (r.status = 'Intersection'), r;
							  }),
							  (e.Intersection.intersectPolygonRectangle = function (t, n, r) {
									var o = n.min(r),
										s = n.max(r),
										a = new e.Point(s.x, o.y),
										c = new e.Point(o.x, s.y),
										h = i.intersectLinePolygon(o, a, t),
										l = i.intersectLinePolygon(a, s, t),
										u = i.intersectLinePolygon(s, c, t),
										f = i.intersectLinePolygon(c, o, t),
										d = new i();
									return (
										d.appendPoints(h.points), d.appendPoints(l.points), d.appendPoints(u.points), d.appendPoints(f.points), d.points.length > 0 && (d.status = 'Intersection'), d
									);
							  }));
					})(e),
					(function (t) {
						'use strict';
						var e = t.fabric || (t.fabric = {});
						function i(t) {
							t ? this._tryParsingColor(t) : this.setSource([0, 0, 0, 1]);
						}
						function n(t, e, i) {
							return i < 0 && (i += 1), i > 1 && (i -= 1), i < 1 / 6 ? t + 6 * (e - t) * i : i < 0.5 ? e : i < 2 / 3 ? t + (e - t) * (2 / 3 - i) * 6 : t;
						}
						e.Color
							? e.warn('fabric.Color is already defined.')
							: ((e.Color = i),
							  (e.Color.prototype = {
									_tryParsingColor: function (t) {
										var e;
										t in i.colorNameMap && (t = i.colorNameMap[t]),
											'transparent' === t && (e = [255, 255, 255, 0]),
											e || (e = i.sourceFromHex(t)),
											e || (e = i.sourceFromRgb(t)),
											e || (e = i.sourceFromHsl(t)),
											e || (e = [0, 0, 0, 1]),
											e && this.setSource(e);
									},
									_rgbToHsl: function (t, i, n) {
										(t /= 255), (i /= 255), (n /= 255);
										var r,
											o,
											s,
											a = e.util.array.max([t, i, n]),
											c = e.util.array.min([t, i, n]);
										if (((s = (a + c) / 2), a === c)) r = o = 0;
										else {
											var h = a - c;
											switch (((o = s > 0.5 ? h / (2 - a - c) : h / (a + c)), a)) {
												case t:
													r = (i - n) / h + (i < n ? 6 : 0);
													break;
												case i:
													r = (n - t) / h + 2;
													break;
												case n:
													r = (t - i) / h + 4;
													break;
											}
											r /= 6;
										}
										return [Math.round(360 * r), Math.round(100 * o), Math.round(100 * s)];
									},
									getSource: function () {
										return this._source;
									},
									setSource: function (t) {
										this._source = t;
									},
									toRgb: function () {
										var t = this.getSource();
										return 'rgb(' + t[0] + ',' + t[1] + ',' + t[2] + ')';
									},
									toRgba: function () {
										var t = this.getSource();
										return 'rgba(' + t[0] + ',' + t[1] + ',' + t[2] + ',' + t[3] + ')';
									},
									toHsl: function () {
										var t = this.getSource(),
											e = this._rgbToHsl(t[0], t[1], t[2]);
										return 'hsl(' + e[0] + ',' + e[1] + '%,' + e[2] + '%)';
									},
									toHsla: function () {
										var t = this.getSource(),
											e = this._rgbToHsl(t[0], t[1], t[2]);
										return 'hsla(' + e[0] + ',' + e[1] + '%,' + e[2] + '%,' + t[3] + ')';
									},
									toHex: function () {
										var t,
											e,
											i,
											n = this.getSource();
										return (
											(t = n[0].toString(16)),
											(t = 1 === t.length ? '0' + t : t),
											(e = n[1].toString(16)),
											(e = 1 === e.length ? '0' + e : e),
											(i = n[2].toString(16)),
											(i = 1 === i.length ? '0' + i : i),
											t.toUpperCase() + e.toUpperCase() + i.toUpperCase()
										);
									},
									toHexa: function () {
										var t,
											e = this.getSource();
										return (t = Math.round(255 * e[3])), (t = t.toString(16)), (t = 1 === t.length ? '0' + t : t), this.toHex() + t.toUpperCase();
									},
									getAlpha: function () {
										return this.getSource()[3];
									},
									setAlpha: function (t) {
										var e = this.getSource();
										return (e[3] = t), this.setSource(e), this;
									},
									toGrayscale: function () {
										var t = this.getSource(),
											e = parseInt((0.3 * t[0] + 0.59 * t[1] + 0.11 * t[2]).toFixed(0), 10),
											i = t[3];
										return this.setSource([e, e, e, i]), this;
									},
									toBlackWhite: function (t) {
										var e = this.getSource(),
											i = (0.3 * e[0] + 0.59 * e[1] + 0.11 * e[2]).toFixed(0),
											n = e[3];
										return (t = t || 127), (i = Number(i) < Number(t) ? 0 : 255), this.setSource([i, i, i, n]), this;
									},
									overlayWith: function (t) {
										t instanceof i || (t = new i(t));
										var e,
											n = [],
											r = this.getAlpha(),
											o = 0.5,
											s = this.getSource(),
											a = t.getSource();
										for (e = 0; e < 3; e++) n.push(Math.round(s[e] * (1 - o) + a[e] * o));
										return (n[3] = r), this.setSource(n), this;
									}
							  }),
							  (e.Color.reRGBa = /^rgba?\(\s*(\d{1,3}(?:\.\d+)?\%?)\s*,\s*(\d{1,3}(?:\.\d+)?\%?)\s*,\s*(\d{1,3}(?:\.\d+)?\%?)\s*(?:\s*,\s*((?:\d*\.?\d+)?)\s*)?\)$/i),
							  (e.Color.reHSLa = /^hsla?\(\s*(\d{1,3})\s*,\s*(\d{1,3}\%)\s*,\s*(\d{1,3}\%)\s*(?:\s*,\s*(\d+(?:\.\d+)?)\s*)?\)$/i),
							  (e.Color.reHex = /^#?([0-9a-f]{8}|[0-9a-f]{6}|[0-9a-f]{4}|[0-9a-f]{3})$/i),
							  (e.Color.colorNameMap = {
									aliceblue: '#F0F8FF',
									antiquewhite: '#FAEBD7',
									aqua: '#00FFFF',
									aquamarine: '#7FFFD4',
									azure: '#F0FFFF',
									beige: '#F5F5DC',
									bisque: '#FFE4C4',
									black: '#000000',
									blanchedalmond: '#FFEBCD',
									blue: '#0000FF',
									blueviolet: '#8A2BE2',
									brown: '#A52A2A',
									burlywood: '#DEB887',
									cadetblue: '#5F9EA0',
									chartreuse: '#7FFF00',
									chocolate: '#D2691E',
									coral: '#FF7F50',
									cornflowerblue: '#6495ED',
									cornsilk: '#FFF8DC',
									crimson: '#DC143C',
									cyan: '#00FFFF',
									darkblue: '#00008B',
									darkcyan: '#008B8B',
									darkgoldenrod: '#B8860B',
									darkgray: '#A9A9A9',
									darkgrey: '#A9A9A9',
									darkgreen: '#006400',
									darkkhaki: '#BDB76B',
									darkmagenta: '#8B008B',
									darkolivegreen: '#556B2F',
									darkorange: '#FF8C00',
									darkorchid: '#9932CC',
									darkred: '#8B0000',
									darksalmon: '#E9967A',
									darkseagreen: '#8FBC8F',
									darkslateblue: '#483D8B',
									darkslategray: '#2F4F4F',
									darkslategrey: '#2F4F4F',
									darkturquoise: '#00CED1',
									darkviolet: '#9400D3',
									deeppink: '#FF1493',
									deepskyblue: '#00BFFF',
									dimgray: '#696969',
									dimgrey: '#696969',
									dodgerblue: '#1E90FF',
									firebrick: '#B22222',
									floralwhite: '#FFFAF0',
									forestgreen: '#228B22',
									fuchsia: '#FF00FF',
									gainsboro: '#DCDCDC',
									ghostwhite: '#F8F8FF',
									gold: '#FFD700',
									goldenrod: '#DAA520',
									gray: '#808080',
									grey: '#808080',
									green: '#008000',
									greenyellow: '#ADFF2F',
									honeydew: '#F0FFF0',
									hotpink: '#FF69B4',
									indianred: '#CD5C5C',
									indigo: '#4B0082',
									ivory: '#FFFFF0',
									khaki: '#F0E68C',
									lavender: '#E6E6FA',
									lavenderblush: '#FFF0F5',
									lawngreen: '#7CFC00',
									lemonchiffon: '#FFFACD',
									lightblue: '#ADD8E6',
									lightcoral: '#F08080',
									lightcyan: '#E0FFFF',
									lightgoldenrodyellow: '#FAFAD2',
									lightgray: '#D3D3D3',
									lightgrey: '#D3D3D3',
									lightgreen: '#90EE90',
									lightpink: '#FFB6C1',
									lightsalmon: '#FFA07A',
									lightseagreen: '#20B2AA',
									lightskyblue: '#87CEFA',
									lightslategray: '#778899',
									lightslategrey: '#778899',
									lightsteelblue: '#B0C4DE',
									lightyellow: '#FFFFE0',
									lime: '#00FF00',
									limegreen: '#32CD32',
									linen: '#FAF0E6',
									magenta: '#FF00FF',
									maroon: '#800000',
									mediumaquamarine: '#66CDAA',
									mediumblue: '#0000CD',
									mediumorchid: '#BA55D3',
									mediumpurple: '#9370DB',
									mediumseagreen: '#3CB371',
									mediumslateblue: '#7B68EE',
									mediumspringgreen: '#00FA9A',
									mediumturquoise: '#48D1CC',
									mediumvioletred: '#C71585',
									midnightblue: '#191970',
									mintcream: '#F5FFFA',
									mistyrose: '#FFE4E1',
									moccasin: '#FFE4B5',
									navajowhite: '#FFDEAD',
									navy: '#000080',
									oldlace: '#FDF5E6',
									olive: '#808000',
									olivedrab: '#6B8E23',
									orange: '#FFA500',
									orangered: '#FF4500',
									orchid: '#DA70D6',
									palegoldenrod: '#EEE8AA',
									palegreen: '#98FB98',
									paleturquoise: '#AFEEEE',
									palevioletred: '#DB7093',
									papayawhip: '#FFEFD5',
									peachpuff: '#FFDAB9',
									peru: '#CD853F',
									pink: '#FFC0CB',
									plum: '#DDA0DD',
									powderblue: '#B0E0E6',
									purple: '#800080',
									rebeccapurple: '#663399',
									red: '#FF0000',
									rosybrown: '#BC8F8F',
									royalblue: '#4169E1',
									saddlebrown: '#8B4513',
									salmon: '#FA8072',
									sandybrown: '#F4A460',
									seagreen: '#2E8B57',
									seashell: '#FFF5EE',
									sienna: '#A0522D',
									silver: '#C0C0C0',
									skyblue: '#87CEEB',
									slateblue: '#6A5ACD',
									slategray: '#708090',
									slategrey: '#708090',
									snow: '#FFFAFA',
									springgreen: '#00FF7F',
									steelblue: '#4682B4',
									tan: '#D2B48C',
									teal: '#008080',
									thistle: '#D8BFD8',
									tomato: '#FF6347',
									turquoise: '#40E0D0',
									violet: '#EE82EE',
									wheat: '#F5DEB3',
									white: '#FFFFFF',
									whitesmoke: '#F5F5F5',
									yellow: '#FFFF00',
									yellowgreen: '#9ACD32'
							  }),
							  (e.Color.fromRgb = function (t) {
									return i.fromSource(i.sourceFromRgb(t));
							  }),
							  (e.Color.sourceFromRgb = function (t) {
									var e = t.match(i.reRGBa);
									if (e) {
										var n = (parseInt(e[1], 10) / (/%$/.test(e[1]) ? 100 : 1)) * (/%$/.test(e[1]) ? 255 : 1),
											r = (parseInt(e[2], 10) / (/%$/.test(e[2]) ? 100 : 1)) * (/%$/.test(e[2]) ? 255 : 1),
											o = (parseInt(e[3], 10) / (/%$/.test(e[3]) ? 100 : 1)) * (/%$/.test(e[3]) ? 255 : 1);
										return [parseInt(n, 10), parseInt(r, 10), parseInt(o, 10), e[4] ? parseFloat(e[4]) : 1];
									}
							  }),
							  (e.Color.fromRgba = i.fromRgb),
							  (e.Color.fromHsl = function (t) {
									return i.fromSource(i.sourceFromHsl(t));
							  }),
							  (e.Color.sourceFromHsl = function (t) {
									var e = t.match(i.reHSLa);
									if (e) {
										var r,
											o,
											s,
											a = (((parseFloat(e[1]) % 360) + 360) % 360) / 360,
											c = parseFloat(e[2]) / (/%$/.test(e[2]) ? 100 : 1),
											h = parseFloat(e[3]) / (/%$/.test(e[3]) ? 100 : 1);
										if (0 === c) r = o = s = h;
										else {
											var l = h <= 0.5 ? h * (c + 1) : h + c - h * c,
												u = 2 * h - l;
											(r = n(u, l, a + 1 / 3)), (o = n(u, l, a)), (s = n(u, l, a - 1 / 3));
										}
										return [Math.round(255 * r), Math.round(255 * o), Math.round(255 * s), e[4] ? parseFloat(e[4]) : 1];
									}
							  }),
							  (e.Color.fromHsla = i.fromHsl),
							  (e.Color.fromHex = function (t) {
									return i.fromSource(i.sourceFromHex(t));
							  }),
							  (e.Color.sourceFromHex = function (t) {
									if (t.match(i.reHex)) {
										var e = t.slice(t.indexOf('#') + 1),
											n = 3 === e.length || 4 === e.length,
											r = 8 === e.length || 4 === e.length,
											o = n ? e.charAt(0) + e.charAt(0) : e.substring(0, 2),
											s = n ? e.charAt(1) + e.charAt(1) : e.substring(2, 4),
											a = n ? e.charAt(2) + e.charAt(2) : e.substring(4, 6),
											c = r ? (n ? e.charAt(3) + e.charAt(3) : e.substring(6, 8)) : 'FF';
										return [parseInt(o, 16), parseInt(s, 16), parseInt(a, 16), parseFloat((parseInt(c, 16) / 255).toFixed(2))];
									}
							  }),
							  (e.Color.fromSource = function (t) {
									var e = new i();
									return e.setSource(t), e;
							  }));
					})(e),
					(function (t) {
						'use strict';
						var e = t.fabric || (t.fabric = {}),
							i = ['e', 'se', 's', 'sw', 'w', 'nw', 'n', 'ne', 'e'],
							n = ['ns', 'nesw', 'ew', 'nwse'],
							r = {},
							o = 'left',
							s = 'top',
							a = 'right',
							c = 'bottom',
							h = 'center',
							l = { top: c, bottom: s, left: a, right: o, center: h },
							u = e.util.radiansToDegrees,
							f =
								Math.sign ||
								function (t) {
									return (t > 0) - (t < 0) || +t;
								};
						function d(t, e) {
							var i = t.angle + u(Math.atan2(e.y, e.x)) + 360;
							return Math.round((i % 360) / 45);
						}
						function p(t, i) {
							var n = i.transform.target,
								r = n.canvas,
								o = e.util.object.clone(i);
							(o.target = n), r && r.fire('object:' + t, o), n.fire(t, i);
						}
						function g(t, e) {
							var i = e.canvas,
								n = i.uniScaleKey,
								r = t[n];
							return (i.uniformScaling && !r) || (!i.uniformScaling && r);
						}
						function v(t) {
							return t.originX === h && t.originY === h;
						}
						function m(t, e, i) {
							var n = t.lockScalingX,
								r = t.lockScalingY;
							return !(!n || !r) || !(e || (!n && !r) || !i) || !(!n || 'x' !== e) || !(!r || 'y' !== e);
						}
						function y(t, e, n) {
							var r = 'not-allowed',
								o = g(t, n),
								s = '';
							if ((0 !== e.x && 0 === e.y ? (s = 'x') : 0 === e.x && 0 !== e.y && (s = 'y'), m(n, s, o))) return r;
							var a = d(n, e);
							return i[a] + '-resize';
						}
						function b(t, e, i) {
							var r = 'not-allowed';
							if (0 !== e.x && i.lockSkewingY) return r;
							if (0 !== e.y && i.lockSkewingX) return r;
							var o = d(i, e) % 4;
							return n[o] + '-resize';
						}
						function x(t, e, i) {
							return t[i.canvas.altActionKey] ? r.skewCursorStyleHandler(t, e, i) : r.scaleCursorStyleHandler(t, e, i);
						}
						function _(t, e, i) {
							var n = t[i.canvas.altActionKey];
							return 0 === e.x ? (n ? 'skewX' : 'scaleY') : 0 === e.y ? (n ? 'skewY' : 'scaleX') : void 0;
						}
						function w(t, e, i) {
							return i.lockRotation ? 'not-allowed' : e.cursorStyle;
						}
						function C(t, e, i, n) {
							return { e: t, transform: e, pointer: { x: i, y: n } };
						}
						function S(t) {
							return function (e, i, n, r) {
								var o = i.target,
									s = o.getCenterPoint(),
									a = o.translateToOriginPoint(s, i.originX, i.originY),
									c = t(e, i, n, r);
								return o.setPositionByOrigin(a, i.originX, i.originY), c;
							};
						}
						function T(t, e) {
							return function (i, n, r, o) {
								var s = e(i, n, r, o);
								return s && p(t, C(i, n, r, o)), s;
							};
						}
						function O(t, i, n, r, o) {
							var s = t.target,
								a = s.controls[t.corner],
								c = s.canvas.getZoom(),
								h = s.padding / c,
								l = s.toLocalPoint(new e.Point(r, o), i, n);
							return l.x >= h && (l.x -= h), l.x <= -h && (l.x += h), l.y >= h && (l.y -= h), l.y <= h && (l.y += h), (l.x -= a.offsetX), (l.y -= a.offsetY), l;
						}
						function k(t) {
							return t.flipX !== t.flipY;
						}
						function P(t, e, i, n, r) {
							if (0 !== t[e]) {
								var o = t._getTransformedDimensions()[n],
									s = (r / o) * t[i];
								t.set(i, s);
							}
						}
						function E(t, e, i, n) {
							var r,
								h = e.target,
								l = h._getTransformedDimensions(0, h.skewY),
								f = O(e, e.originX, e.originY, i, n),
								d = Math.abs(2 * f.x) - l.x,
								p = h.skewX;
							d < 2
								? (r = 0)
								: ((r = u(Math.atan2(d / h.scaleX, l.y / h.scaleY))), e.originX === o && e.originY === c && (r = -r), e.originX === a && e.originY === s && (r = -r), k(h) && (r = -r));
							var g = p !== r;
							if (g) {
								var v = h._getTransformedDimensions().y;
								h.set('skewX', r), P(h, 'skewY', 'scaleY', 'y', v);
							}
							return g;
						}
						function M(t, e, i, n) {
							var r,
								h = e.target,
								l = h._getTransformedDimensions(h.skewX, 0),
								f = O(e, e.originX, e.originY, i, n),
								d = Math.abs(2 * f.y) - l.y,
								p = h.skewY;
							d < 2
								? (r = 0)
								: ((r = u(Math.atan2(d / h.scaleY, l.x / h.scaleX))), e.originX === o && e.originY === c && (r = -r), e.originX === a && e.originY === s && (r = -r), k(h) && (r = -r));
							var g = p !== r;
							if (g) {
								var v = h._getTransformedDimensions().x;
								h.set('skewY', r), P(h, 'skewX', 'scaleX', 'x', v);
							}
							return g;
						}
						function j(t, e, i, n) {
							var r,
								c = e.target,
								l = c.skewX,
								u = e.originY;
							if (c.lockSkewingX) return !1;
							if (0 === l) {
								var f = O(e, h, h, i, n);
								r = f.x > 0 ? o : a;
							} else l > 0 && (r = u === s ? o : a), l < 0 && (r = u === s ? a : o), k(c) && (r = r === o ? a : o);
							e.originX = r;
							var d = T('skewing', S(E));
							return d(t, e, i, n);
						}
						function D(t, e, i, n) {
							var r,
								a = e.target,
								l = a.skewY,
								u = e.originX;
							if (a.lockSkewingY) return !1;
							if (0 === l) {
								var f = O(e, h, h, i, n);
								r = f.y > 0 ? s : c;
							} else l > 0 && (r = u === o ? s : c), l < 0 && (r = u === o ? c : s), k(a) && (r = r === s ? c : s);
							e.originY = r;
							var d = T('skewing', S(M));
							return d(t, e, i, n);
						}
						function A(t, e, i, n) {
							var r = e,
								o = r.target,
								s = o.translateToOriginPoint(o.getCenterPoint(), r.originX, r.originY);
							if (o.lockRotation) return !1;
							var a = Math.atan2(r.ey - s.y, r.ex - s.x),
								c = Math.atan2(n - s.y, i - s.x),
								h = u(c - a + r.theta),
								l = !0;
							if (o.snapAngle > 0) {
								var f = o.snapAngle,
									d = o.snapThreshold || f,
									p = Math.ceil(h / f) * f,
									g = Math.floor(h / f) * f;
								Math.abs(h - g) < d ? (h = g) : Math.abs(h - p) < d && (h = p);
							}
							return h < 0 && (h = 360 + h), (h %= 360), (l = o.angle !== h), (o.angle = h), l;
						}
						function F(t, e, i, n, r) {
							r = r || {};
							var o,
								s,
								a,
								c,
								h,
								u,
								d = e.target,
								p = d.lockScalingX,
								y = d.lockScalingY,
								b = r.by,
								x = g(t, d),
								_ = m(d, b, x),
								w = e.gestureScale;
							if (_) return !1;
							if (w) (s = e.scaleX * w), (a = e.scaleY * w);
							else {
								if (
									((o = O(e, e.originX, e.originY, i, n)),
									(h = 'y' !== b ? f(o.x) : 1),
									(u = 'x' !== b ? f(o.y) : 1),
									e.signX || (e.signX = h),
									e.signY || (e.signY = u),
									d.lockScalingFlip && (e.signX !== h || e.signY !== u))
								)
									return !1;
								if (((c = d._getTransformedDimensions()), x && !b)) {
									var C = Math.abs(o.x) + Math.abs(o.y),
										S = e.original,
										T = Math.abs((c.x * S.scaleX) / d.scaleX) + Math.abs((c.y * S.scaleY) / d.scaleY),
										k = C / T;
									(s = S.scaleX * k), (a = S.scaleY * k);
								} else (s = Math.abs((o.x * d.scaleX) / c.x)), (a = Math.abs((o.y * d.scaleY) / c.y));
								v(e) && ((s *= 2), (a *= 2)),
									e.signX !== h && 'y' !== b && ((e.originX = l[e.originX]), (s *= -1), (e.signX = h)),
									e.signY !== u && 'x' !== b && ((e.originY = l[e.originY]), (a *= -1), (e.signY = u));
							}
							var P = d.scaleX,
								E = d.scaleY;
							return b ? ('x' === b && d.set('scaleX', s), 'y' === b && d.set('scaleY', a)) : (!p && d.set('scaleX', s), !y && d.set('scaleY', a)), P !== d.scaleX || E !== d.scaleY;
						}
						function L(t, e, i, n) {
							return F(t, e, i, n);
						}
						function I(t, e, i, n) {
							return F(t, e, i, n, { by: 'x' });
						}
						function R(t, e, i, n) {
							return F(t, e, i, n, { by: 'y' });
						}
						function B(t, e, i, n) {
							return t[e.target.canvas.altActionKey] ? r.skewHandlerX(t, e, i, n) : r.scalingY(t, e, i, n);
						}
						function z(t, e, i, n) {
							return t[e.target.canvas.altActionKey] ? r.skewHandlerY(t, e, i, n) : r.scalingX(t, e, i, n);
						}
						function X(t, e, i, n) {
							var r = e.target,
								o = O(e, e.originX, e.originY, i, n),
								s = r.strokeWidth / (r.strokeUniform ? r.scaleX : 1),
								a = v(e) ? 2 : 1,
								c = r.width,
								h = Math.abs((o.x * a) / r.scaleX) - s;
							return r.set('width', Math.max(h, 0)), c !== h;
						}
						function W(t, e, i, n) {
							var r = e.target,
								o = i - e.offsetX,
								s = n - e.offsetY,
								a = !r.get('lockMovementX') && r.left !== o,
								c = !r.get('lockMovementY') && r.top !== s;
							return a && r.set('left', o), c && r.set('top', s), (a || c) && p('moving', C(t, e, i, n)), a || c;
						}
						(r.scaleCursorStyleHandler = y),
							(r.skewCursorStyleHandler = b),
							(r.scaleSkewCursorStyleHandler = x),
							(r.rotationWithSnapping = T('rotating', S(A))),
							(r.scalingEqually = T('scaling', S(L))),
							(r.scalingX = T('scaling', S(I))),
							(r.scalingY = T('scaling', S(R))),
							(r.scalingYOrSkewingX = B),
							(r.scalingXOrSkewingY = z),
							(r.changeWidth = T('resizing', S(X))),
							(r.skewHandlerX = j),
							(r.skewHandlerY = D),
							(r.dragHandler = W),
							(r.scaleOrSkewActionName = _),
							(r.rotationStyleHandler = w),
							(r.fireEvent = p),
							(r.wrapWithFixedAnchor = S),
							(r.wrapWithFireEvent = T),
							(r.getLocalPoint = O),
							(e.controlsUtils = r);
					})(e),
					(function (t) {
						'use strict';
						var e = t.fabric || (t.fabric = {}),
							i = e.util.degreesToRadians,
							n = e.controlsUtils;
						function r(t, e, i, n, r) {
							n = n || {};
							var o,
								s = this.sizeX || n.cornerSize || r.cornerSize,
								a = this.sizeY || n.cornerSize || r.cornerSize,
								c = 'undefined' !== typeof n.transparentCorners ? n.transparentCorners : r.transparentCorners,
								h = c ? 'stroke' : 'fill',
								l = !c && (n.cornerStrokeColor || r.cornerStrokeColor),
								u = e,
								f = i;
							t.save(),
								(t.fillStyle = n.cornerColor || r.cornerColor),
								(t.strokeStyle = n.cornerStrokeColor || r.cornerStrokeColor),
								s > a ? ((o = s), t.scale(1, a / s), (f = (i * s) / a)) : a > s ? ((o = a), t.scale(s / a, 1), (u = (e * a) / s)) : (o = s),
								(t.lineWidth = 1),
								t.beginPath(),
								t.arc(u, f, o / 2, 0, 2 * Math.PI, !1),
								t[h](),
								l && t.stroke(),
								t.restore();
						}
						function o(t, e, n, r, o) {
							r = r || {};
							var s = this.sizeX || r.cornerSize || o.cornerSize,
								a = this.sizeY || r.cornerSize || o.cornerSize,
								c = 'undefined' !== typeof r.transparentCorners ? r.transparentCorners : o.transparentCorners,
								h = c ? 'stroke' : 'fill',
								l = !c && (r.cornerStrokeColor || o.cornerStrokeColor),
								u = s / 2,
								f = a / 2;
							t.save(),
								(t.fillStyle = r.cornerColor || o.cornerColor),
								(t.strokeStyle = r.cornerStrokeColor || o.cornerStrokeColor),
								(t.lineWidth = 1),
								t.translate(e, n),
								t.rotate(i(o.angle)),
								t[h + 'Rect'](-u, -f, s, a),
								l && t.strokeRect(-u, -f, s, a),
								t.restore();
						}
						(n.renderCircleControl = r), (n.renderSquareControl = o);
					})(e),
					(function (t) {
						'use strict';
						var e = t.fabric || (t.fabric = {});
						function i(t) {
							for (var e in t) this[e] = t[e];
						}
						(e.Control = i),
							(e.Control.prototype = {
								visible: !0,
								actionName: 'scale',
								angle: 0,
								x: 0,
								y: 0,
								offsetX: 0,
								offsetY: 0,
								sizeX: null,
								sizeY: null,
								touchSizeX: null,
								touchSizeY: null,
								cursorStyle: 'crosshair',
								withConnection: !1,
								actionHandler: function () {},
								mouseDownHandler: function () {},
								mouseUpHandler: function () {},
								getActionHandler: function () {
									return this.actionHandler;
								},
								getMouseDownHandler: function () {
									return this.mouseDownHandler;
								},
								getMouseUpHandler: function () {
									return this.mouseUpHandler;
								},
								cursorStyleHandler: function (t, e) {
									return e.cursorStyle;
								},
								getActionName: function (t, e) {
									return e.actionName;
								},
								getVisibility: function (t, e) {
									var i = t._controlsVisibility;
									return i && 'undefined' !== typeof i[e] ? i[e] : this.visible;
								},
								setVisibility: function (t) {
									this.visible = t;
								},
								positionHandler: function (t, i) {
									var n = e.util.transformPoint({ x: this.x * t.x + this.offsetX, y: this.y * t.y + this.offsetY }, i);
									return n;
								},
								calcCornerCoords: function (t, i, n, r, o) {
									var s,
										a,
										c,
										h,
										l = o ? this.touchSizeX : this.sizeX,
										u = o ? this.touchSizeY : this.sizeY;
									if (l && u && l !== u) {
										var f = Math.atan2(u, l),
											d = Math.sqrt(l * l + u * u) / 2,
											p = f - e.util.degreesToRadians(t),
											g = Math.PI / 2 - f - e.util.degreesToRadians(t);
										(s = d * e.util.cos(p)), (a = d * e.util.sin(p)), (c = d * e.util.cos(g)), (h = d * e.util.sin(g));
									} else {
										var v = l && u ? l : i;
										d = 0.7071067812 * v;
										p = e.util.degreesToRadians(45 - t);
										(s = c = d * e.util.cos(p)), (a = h = d * e.util.sin(p));
									}
									return { tl: { x: n - h, y: r - c }, tr: { x: n + s, y: r - a }, bl: { x: n - s, y: r + a }, br: { x: n + h, y: r + c } };
								},
								render: function (t, i, n, r, o) {
									switch (((r = r || {}), r.cornerStyle || o.cornerStyle)) {
										case 'circle':
											e.controlsUtils.renderCircleControl.call(this, t, i, n, r, o);
											break;
										default:
											e.controlsUtils.renderSquareControl.call(this, t, i, n, r, o);
									}
								}
							});
					})(e),
					(function () {
						function t(t, e) {
							var i,
								r,
								o,
								s,
								a = t.getAttribute('style'),
								c = t.getAttribute('offset') || 0;
							if (((c = parseFloat(c) / (/%$/.test(c) ? 100 : 1)), (c = c < 0 ? 0 : c > 1 ? 1 : c), a)) {
								var h = a.split(/\s*;\s*/);
								for ('' === h[h.length - 1] && h.pop(), s = h.length; s--; ) {
									var l = h[s].split(/\s*:\s*/),
										u = l[0].trim(),
										f = l[1].trim();
									'stop-color' === u ? (i = f) : 'stop-opacity' === u && (o = f);
								}
							}
							return (
								i || (i = t.getAttribute('stop-color') || 'rgb(0,0,0)'),
								o || (o = t.getAttribute('stop-opacity')),
								(i = new n.Color(i)),
								(r = i.getAlpha()),
								(o = isNaN(parseFloat(o)) ? 1 : parseFloat(o)),
								(o *= r * e),
								{ offset: c, color: i.toRgb(), opacity: o }
							);
						}
						function e(t) {
							return { x1: t.getAttribute('x1') || 0, y1: t.getAttribute('y1') || 0, x2: t.getAttribute('x2') || '100%', y2: t.getAttribute('y2') || 0 };
						}
						function i(t) {
							return {
								x1: t.getAttribute('fx') || t.getAttribute('cx') || '50%',
								y1: t.getAttribute('fy') || t.getAttribute('cy') || '50%',
								r1: 0,
								x2: t.getAttribute('cx') || '50%',
								y2: t.getAttribute('cy') || '50%',
								r2: t.getAttribute('r') || '50%'
							};
						}
						var r = n.util.object.clone;
						function o(t, e, i, n) {
							var r, o;
							Object.keys(e).forEach(function (t) {
								(r = e[t]),
									'Infinity' === r
										? (o = 1)
										: '-Infinity' === r
										? (o = 0)
										: ((o = parseFloat(e[t], 10)),
										  'string' === typeof r &&
												/^(\d+\.\d+)%|(\d+)%$/.test(r) &&
												((o *= 0.01),
												'pixels' === n &&
													(('x1' !== t && 'x2' !== t && 'r2' !== t) || (o *= i.viewBoxWidth || i.width), ('y1' !== t && 'y2' !== t) || (o *= i.viewBoxHeight || i.height)))),
									(e[t] = o);
							});
						}
						(n.Gradient = n.util.createClass({
							offsetX: 0,
							offsetY: 0,
							gradientTransform: null,
							gradientUnits: 'pixels',
							type: 'linear',
							initialize: function (t) {
								t || (t = {}), t.coords || (t.coords = {});
								var e,
									i = this;
								Object.keys(t).forEach(function (e) {
									i[e] = t[e];
								}),
									this.id ? (this.id += '_' + n.Object.__uid++) : (this.id = n.Object.__uid++),
									(e = { x1: t.coords.x1 || 0, y1: t.coords.y1 || 0, x2: t.coords.x2 || 0, y2: t.coords.y2 || 0 }),
									'radial' === this.type && ((e.r1 = t.coords.r1 || 0), (e.r2 = t.coords.r2 || 0)),
									(this.coords = e),
									(this.colorStops = t.colorStops.slice());
							},
							addColorStop: function (t) {
								for (var e in t) {
									var i = new n.Color(t[e]);
									this.colorStops.push({ offset: parseFloat(e), color: i.toRgb(), opacity: i.getAlpha() });
								}
								return this;
							},
							toObject: function (t) {
								var e = {
									type: this.type,
									coords: this.coords,
									colorStops: this.colorStops,
									offsetX: this.offsetX,
									offsetY: this.offsetY,
									gradientUnits: this.gradientUnits,
									gradientTransform: this.gradientTransform ? this.gradientTransform.concat() : this.gradientTransform
								};
								return n.util.populateWithProperties(this, e, t), e;
							},
							toSVG: function (t, e) {
								var i,
									o,
									s,
									a,
									c = r(this.coords, !0),
									h = ((e = e || {}), r(this.colorStops, !0)),
									l = c.r1 > c.r2,
									u = this.gradientTransform ? this.gradientTransform.concat() : n.iMatrix.concat(),
									f = -this.offsetX,
									d = -this.offsetY,
									p = !!e.additionalTransform,
									g = 'pixels' === this.gradientUnits ? 'userSpaceOnUse' : 'objectBoundingBox';
								if (
									(h.sort(function (t, e) {
										return t.offset - e.offset;
									}),
									'objectBoundingBox' === g ? ((f /= t.width), (d /= t.height)) : ((f += t.width / 2), (d += t.height / 2)),
									'path' === t.type && 'percentage' !== this.gradientUnits && ((f -= t.pathOffset.x), (d -= t.pathOffset.y)),
									(u[4] -= f),
									(u[5] -= d),
									(a = 'id="SVGID_' + this.id + '" gradientUnits="' + g + '"'),
									(a += ' gradientTransform="' + (p ? e.additionalTransform + ' ' : '') + n.util.matrixToSVG(u) + '" '),
									'linear' === this.type
										? (s = ['<linearGradient ', a, ' x1="', c.x1, '" y1="', c.y1, '" x2="', c.x2, '" y2="', c.y2, '">\n'])
										: 'radial' === this.type &&
										  (s = [
												'<radialGradient ',
												a,
												' cx="',
												l ? c.x1 : c.x2,
												'" cy="',
												l ? c.y1 : c.y2,
												'" r="',
												l ? c.r1 : c.r2,
												'" fx="',
												l ? c.x2 : c.x1,
												'" fy="',
												l ? c.y2 : c.y1,
												'">\n'
										  ]),
									'radial' === this.type)
								) {
									if (l) for (h = h.concat(), h.reverse(), i = 0, o = h.length; i < o; i++) h[i].offset = 1 - h[i].offset;
									var v = Math.min(c.r1, c.r2);
									if (v > 0) {
										var m = Math.max(c.r1, c.r2),
											y = v / m;
										for (i = 0, o = h.length; i < o; i++) h[i].offset += y * (1 - h[i].offset);
									}
								}
								for (i = 0, o = h.length; i < o; i++) {
									var b = h[i];
									s.push(
										'<stop ',
										'offset="',
										100 * b.offset + '%',
										'" style="stop-color:',
										b.color,
										'undefined' !== typeof b.opacity ? ';stop-opacity: ' + b.opacity : ';',
										'"/>\n'
									);
								}
								return s.push('linear' === this.type ? '</linearGradient>\n' : '</radialGradient>\n'), s.join('');
							},
							toLive: function (t) {
								var e,
									i,
									r,
									o = n.util.object.clone(this.coords);
								if (this.type) {
									for (
										'linear' === this.type
											? (e = t.createLinearGradient(o.x1, o.y1, o.x2, o.y2))
											: 'radial' === this.type && (e = t.createRadialGradient(o.x1, o.y1, o.r1, o.x2, o.y2, o.r2)),
											i = 0,
											r = this.colorStops.length;
										i < r;
										i++
									) {
										var s = this.colorStops[i].color,
											a = this.colorStops[i].opacity,
											c = this.colorStops[i].offset;
										'undefined' !== typeof a && (s = new n.Color(s).setAlpha(a).toRgba()), e.addColorStop(c, s);
									}
									return e;
								}
							}
						})),
							n.util.object.extend(n.Gradient, {
								fromElement: function (r, s, a, c) {
									var h = parseFloat(a) / (/%$/.test(a) ? 100 : 1);
									(h = h < 0 ? 0 : h > 1 ? 1 : h), isNaN(h) && (h = 1);
									var l,
										u,
										f,
										d,
										p = r.getElementsByTagName('stop'),
										g = 'userSpaceOnUse' === r.getAttribute('gradientUnits') ? 'pixels' : 'percentage',
										v = r.getAttribute('gradientTransform') || '',
										m = [],
										y = 0,
										b = 0;
									for ('linearGradient' === r.nodeName || 'LINEARGRADIENT' === r.nodeName ? ((l = 'linear'), (u = e(r))) : ((l = 'radial'), (u = i(r))), f = p.length; f--; )
										m.push(t(p[f], h));
									(d = n.parseTransformAttribute(v)), o(s, u, c, g), 'pixels' === g && ((y = -s.left), (b = -s.top));
									var x = new n.Gradient({ id: r.getAttribute('id'), type: l, coords: u, colorStops: m, gradientUnits: g, gradientTransform: d, offsetX: y, offsetY: b });
									return x;
								}
							});
					})(),
					(function () {
						'use strict';
						var t = n.util.toFixed;
						n.Pattern = n.util.createClass({
							repeat: 'repeat',
							offsetX: 0,
							offsetY: 0,
							crossOrigin: '',
							patternTransform: null,
							initialize: function (t, e) {
								if ((t || (t = {}), (this.id = n.Object.__uid++), this.setOptions(t), !t.source || (t.source && 'string' !== typeof t.source))) e && e(this);
								else {
									var i = this;
									(this.source = n.util.createImage()),
										n.util.loadImage(
											t.source,
											function (t, n) {
												(i.source = t), e && e(i, n);
											},
											null,
											this.crossOrigin
										);
								}
							},
							toObject: function (e) {
								var i,
									r,
									o = n.Object.NUM_FRACTION_DIGITS;
								return (
									'string' === typeof this.source.src ? (i = this.source.src) : 'object' === typeof this.source && this.source.toDataURL && (i = this.source.toDataURL()),
									(r = {
										type: 'pattern',
										source: i,
										repeat: this.repeat,
										crossOrigin: this.crossOrigin,
										offsetX: t(this.offsetX, o),
										offsetY: t(this.offsetY, o),
										patternTransform: this.patternTransform ? this.patternTransform.concat() : null
									}),
									n.util.populateWithProperties(this, r, e),
									r
								);
							},
							toSVG: function (t) {
								var e = 'function' === typeof this.source ? this.source() : this.source,
									i = e.width / t.width,
									n = e.height / t.height,
									r = this.offsetX / t.width,
									o = this.offsetY / t.height,
									s = '';
								return (
									('repeat-x' !== this.repeat && 'no-repeat' !== this.repeat) || ((n = 1), o && (n += Math.abs(o))),
									('repeat-y' !== this.repeat && 'no-repeat' !== this.repeat) || ((i = 1), r && (i += Math.abs(r))),
									e.src ? (s = e.src) : e.toDataURL && (s = e.toDataURL()),
									'<pattern id="SVGID_' +
										this.id +
										'" x="' +
										r +
										'" y="' +
										o +
										'" width="' +
										i +
										'" height="' +
										n +
										'">\n<image x="0" y="0" width="' +
										e.width +
										'" height="' +
										e.height +
										'" xlink:href="' +
										s +
										'"></image>\n</pattern>\n'
								);
							},
							setOptions: function (t) {
								for (var e in t) this[e] = t[e];
							},
							toLive: function (t) {
								var e = this.source;
								if (!e) return '';
								if ('undefined' !== typeof e.src) {
									if (!e.complete) return '';
									if (0 === e.naturalWidth || 0 === e.naturalHeight) return '';
								}
								return t.createPattern(e, this.repeat);
							}
						});
					})(),
					(function (t) {
						'use strict';
						var e = t.fabric || (t.fabric = {}),
							i = e.util.toFixed;
						e.Shadow
							? e.warn('fabric.Shadow is already defined.')
							: ((e.Shadow = e.util.createClass({
									color: 'rgb(0,0,0)',
									blur: 0,
									offsetX: 0,
									offsetY: 0,
									affectStroke: !1,
									includeDefaultValues: !0,
									nonScaling: !1,
									initialize: function (t) {
										for (var i in ('string' === typeof t && (t = this._parseShadow(t)), t)) this[i] = t[i];
										this.id = e.Object.__uid++;
									},
									_parseShadow: function (t) {
										var i = t.trim(),
											n = e.Shadow.reOffsetsAndBlur.exec(i) || [],
											r = i.replace(e.Shadow.reOffsetsAndBlur, '') || 'rgb(0,0,0)';
										return { color: r.trim(), offsetX: parseFloat(n[1], 10) || 0, offsetY: parseFloat(n[2], 10) || 0, blur: parseFloat(n[3], 10) || 0 };
									},
									toString: function () {
										return [this.offsetX, this.offsetY, this.blur, this.color].join('px ');
									},
									toSVG: function (t) {
										var n = 40,
											r = 40,
											o = e.Object.NUM_FRACTION_DIGITS,
											s = e.util.rotateVector({ x: this.offsetX, y: this.offsetY }, e.util.degreesToRadians(-t.angle)),
											a = 20,
											c = new e.Color(this.color);
										return (
											t.width && t.height && ((n = 100 * i((Math.abs(s.x) + this.blur) / t.width, o) + a), (r = 100 * i((Math.abs(s.y) + this.blur) / t.height, o) + a)),
											t.flipX && (s.x *= -1),
											t.flipY && (s.y *= -1),
											'<filter id="SVGID_' +
												this.id +
												'" y="-' +
												r +
												'%" height="' +
												(100 + 2 * r) +
												'%" x="-' +
												n +
												'%" width="' +
												(100 + 2 * n) +
												'%" >\n\t<feGaussianBlur in="SourceAlpha" stdDeviation="' +
												i(this.blur ? this.blur / 2 : 0, o) +
												'"></feGaussianBlur>\n\t<feOffset dx="' +
												i(s.x, o) +
												'" dy="' +
												i(s.y, o) +
												'" result="oBlur" ></feOffset>\n\t<feFlood flood-color="' +
												c.toRgb() +
												'" flood-opacity="' +
												c.getAlpha() +
												'"/>\n\t<feComposite in2="oBlur" operator="in" />\n\t<feMerge>\n\t\t<feMergeNode></feMergeNode>\n\t\t<feMergeNode in="SourceGraphic"></feMergeNode>\n\t</feMerge>\n</filter>\n'
										);
									},
									toObject: function () {
										if (this.includeDefaultValues)
											return { color: this.color, blur: this.blur, offsetX: this.offsetX, offsetY: this.offsetY, affectStroke: this.affectStroke, nonScaling: this.nonScaling };
										var t = {},
											i = e.Shadow.prototype;
										return (
											['color', 'blur', 'offsetX', 'offsetY', 'affectStroke', 'nonScaling'].forEach(function (e) {
												this[e] !== i[e] && (t[e] = this[e]);
											}, this),
											t
										);
									}
							  })),
							  (e.Shadow.reOffsetsAndBlur = /(?:\s|^)(-?\d+(?:\.\d*)?(?:px)?(?:\s?|$))?(-?\d+(?:\.\d*)?(?:px)?(?:\s?|$))?(\d+(?:\.\d*)?(?:px)?)?(?:\s?|$)(?:$|\s)/));
					})(e),
					(function () {
						'use strict';
						if (n.StaticCanvas) n.warn('fabric.StaticCanvas is already defined.');
						else {
							var t = n.util.object.extend,
								e = n.util.getElementOffset,
								i = n.util.removeFromArray,
								r = n.util.toFixed,
								o = n.util.transformPoint,
								s = n.util.invertTransform,
								a = n.util.getNodeCanvas,
								c = n.util.createCanvasElement,
								h = new Error('Could not initialize `canvas` element');
							(n.StaticCanvas = n.util.createClass(n.CommonMethods, {
								initialize: function (t, e) {
									e || (e = {}), (this.renderAndResetBound = this.renderAndReset.bind(this)), (this.requestRenderAllBound = this.requestRenderAll.bind(this)), this._initStatic(t, e);
								},
								backgroundColor: '',
								backgroundImage: null,
								overlayColor: '',
								overlayImage: null,
								includeDefaultValues: !0,
								stateful: !1,
								renderOnAddRemove: !0,
								controlsAboveOverlay: !1,
								allowTouchScrolling: !1,
								imageSmoothingEnabled: !0,
								viewportTransform: n.iMatrix.concat(),
								backgroundVpt: !0,
								overlayVpt: !0,
								enableRetinaScaling: !0,
								vptCoords: {},
								skipOffscreen: !0,
								clipPath: void 0,
								_initStatic: function (t, e) {
									var i = this.requestRenderAllBound;
									(this._objects = []),
										this._createLowerCanvas(t),
										this._initOptions(e),
										this.interactive || this._initRetinaScaling(),
										e.overlayImage && this.setOverlayImage(e.overlayImage, i),
										e.backgroundImage && this.setBackgroundImage(e.backgroundImage, i),
										e.backgroundColor && this.setBackgroundColor(e.backgroundColor, i),
										e.overlayColor && this.setOverlayColor(e.overlayColor, i),
										this.calcOffset();
								},
								_isRetinaScaling: function () {
									return n.devicePixelRatio > 1 && this.enableRetinaScaling;
								},
								getRetinaScaling: function () {
									return this._isRetinaScaling() ? Math.max(1, n.devicePixelRatio) : 1;
								},
								_initRetinaScaling: function () {
									if (this._isRetinaScaling()) {
										var t = n.devicePixelRatio;
										this.__initRetinaScaling(t, this.lowerCanvasEl, this.contextContainer), this.upperCanvasEl && this.__initRetinaScaling(t, this.upperCanvasEl, this.contextTop);
									}
								},
								__initRetinaScaling: function (t, e, i) {
									e.setAttribute('width', this.width * t), e.setAttribute('height', this.height * t), i.scale(t, t);
								},
								calcOffset: function () {
									return (this._offset = e(this.lowerCanvasEl)), this;
								},
								setOverlayImage: function (t, e, i) {
									return this.__setBgOverlayImage('overlayImage', t, e, i);
								},
								setBackgroundImage: function (t, e, i) {
									return this.__setBgOverlayImage('backgroundImage', t, e, i);
								},
								setOverlayColor: function (t, e) {
									return this.__setBgOverlayColor('overlayColor', t, e);
								},
								setBackgroundColor: function (t, e) {
									return this.__setBgOverlayColor('backgroundColor', t, e);
								},
								__setBgOverlayImage: function (t, e, i, r) {
									return (
										'string' === typeof e
											? n.util.loadImage(
													e,
													function (e, o) {
														if (e) {
															var s = new n.Image(e, r);
															(this[t] = s), (s.canvas = this);
														}
														i && i(e, o);
													},
													this,
													r && r.crossOrigin
											  )
											: (r && e.setOptions(r), (this[t] = e), e && (e.canvas = this), i && i(e, !1)),
										this
									);
								},
								__setBgOverlayColor: function (t, e, i) {
									return (this[t] = e), this._initGradient(e, t), this._initPattern(e, t, i), this;
								},
								_createCanvasElement: function () {
									var t = c();
									if (!t) throw h;
									if ((t.style || (t.style = {}), 'undefined' === typeof t.getContext)) throw h;
									return t;
								},
								_initOptions: function (t) {
									var e = this.lowerCanvasEl;
									this._setOptions(t),
										(this.width = this.width || parseInt(e.width, 10) || 0),
										(this.height = this.height || parseInt(e.height, 10) || 0),
										this.lowerCanvasEl.style &&
											((e.width = this.width),
											(e.height = this.height),
											(e.style.width = this.width + 'px'),
											(e.style.height = this.height + 'px'),
											(this.viewportTransform = this.viewportTransform.slice()));
								},
								_createLowerCanvas: function (t) {
									t && t.getContext ? (this.lowerCanvasEl = t) : (this.lowerCanvasEl = n.util.getById(t) || this._createCanvasElement()),
										n.util.addClass(this.lowerCanvasEl, 'lower-canvas'),
										(this._originalCanvasStyle = this.lowerCanvasEl.style),
										this.interactive && this._applyCanvasStyle(this.lowerCanvasEl),
										(this.contextContainer = this.lowerCanvasEl.getContext('2d'));
								},
								getWidth: function () {
									return this.width;
								},
								getHeight: function () {
									return this.height;
								},
								setWidth: function (t, e) {
									return this.setDimensions({ width: t }, e);
								},
								setHeight: function (t, e) {
									return this.setDimensions({ height: t }, e);
								},
								setDimensions: function (t, e) {
									var i;
									for (var n in ((e = e || {}), t))
										(i = t[n]), e.cssOnly || (this._setBackstoreDimension(n, t[n]), (i += 'px'), (this.hasLostContext = !0)), e.backstoreOnly || this._setCssDimension(n, i);
									return (
										this._isCurrentlyDrawing && this.freeDrawingBrush && this.freeDrawingBrush._setBrushStyles(this.contextTop),
										this._initRetinaScaling(),
										this.calcOffset(),
										e.cssOnly || this.requestRenderAll(),
										this
									);
								},
								_setBackstoreDimension: function (t, e) {
									return (this.lowerCanvasEl[t] = e), this.upperCanvasEl && (this.upperCanvasEl[t] = e), this.cacheCanvasEl && (this.cacheCanvasEl[t] = e), (this[t] = e), this;
								},
								_setCssDimension: function (t, e) {
									return (this.lowerCanvasEl.style[t] = e), this.upperCanvasEl && (this.upperCanvasEl.style[t] = e), this.wrapperEl && (this.wrapperEl.style[t] = e), this;
								},
								getZoom: function () {
									return this.viewportTransform[0];
								},
								setViewportTransform: function (t) {
									var e,
										i,
										n,
										r = this._activeObject,
										o = this.backgroundImage,
										s = this.overlayImage;
									for (this.viewportTransform = t, i = 0, n = this._objects.length; i < n; i++) (e = this._objects[i]), e.group || e.setCoords(!0);
									return r && r.setCoords(), o && o.setCoords(!0), s && s.setCoords(!0), this.calcViewportBoundaries(), this.renderOnAddRemove && this.requestRenderAll(), this;
								},
								zoomToPoint: function (t, e) {
									var i = t,
										n = this.viewportTransform.slice(0);
									(t = o(t, s(this.viewportTransform))), (n[0] = e), (n[3] = e);
									var r = o(t, n);
									return (n[4] += i.x - r.x), (n[5] += i.y - r.y), this.setViewportTransform(n);
								},
								setZoom: function (t) {
									return this.zoomToPoint(new n.Point(0, 0), t), this;
								},
								absolutePan: function (t) {
									var e = this.viewportTransform.slice(0);
									return (e[4] = -t.x), (e[5] = -t.y), this.setViewportTransform(e);
								},
								relativePan: function (t) {
									return this.absolutePan(new n.Point(-t.x - this.viewportTransform[4], -t.y - this.viewportTransform[5]));
								},
								getElement: function () {
									return this.lowerCanvasEl;
								},
								_onObjectAdded: function (t) {
									this.stateful && t.setupState(), t._set('canvas', this), t.setCoords(), this.fire('object:added', { target: t }), t.fire('added');
								},
								_onObjectRemoved: function (t) {
									this.fire('object:removed', { target: t }), t.fire('removed'), delete t.canvas;
								},
								clearContext: function (t) {
									return t.clearRect(0, 0, this.width, this.height), this;
								},
								getContext: function () {
									return this.contextContainer;
								},
								clear: function () {
									return (
										this.remove.apply(this, this.getObjects()),
										(this.backgroundImage = null),
										(this.overlayImage = null),
										(this.backgroundColor = ''),
										(this.overlayColor = ''),
										this._hasITextHandlers && (this.off('mouse:up', this._mouseUpITextHandler), (this._iTextInstances = null), (this._hasITextHandlers = !1)),
										this.clearContext(this.contextContainer),
										this.fire('canvas:cleared'),
										this.renderOnAddRemove && this.requestRenderAll(),
										this
									);
								},
								renderAll: function () {
									var t = this.contextContainer;
									return this.renderCanvas(t, this._objects), this;
								},
								renderAndReset: function () {
									(this.isRendering = 0), this.renderAll();
								},
								requestRenderAll: function () {
									return this.isRendering || (this.isRendering = n.util.requestAnimFrame(this.renderAndResetBound)), this;
								},
								calcViewportBoundaries: function () {
									var t = {},
										e = this.width,
										i = this.height,
										r = s(this.viewportTransform);
									return (
										(t.tl = o({ x: 0, y: 0 }, r)),
										(t.br = o({ x: e, y: i }, r)),
										(t.tr = new n.Point(t.br.x, t.tl.y)),
										(t.bl = new n.Point(t.tl.x, t.br.y)),
										(this.vptCoords = t),
										t
									);
								},
								cancelRequestedRender: function () {
									this.isRendering && (n.util.cancelAnimFrame(this.isRendering), (this.isRendering = 0));
								},
								renderCanvas: function (t, e) {
									var i = this.viewportTransform,
										r = this.clipPath;
									this.cancelRequestedRender(),
										this.calcViewportBoundaries(),
										this.clearContext(t),
										n.util.setImageSmoothing(t, this.imageSmoothingEnabled),
										this.fire('before:render', { ctx: t }),
										this._renderBackground(t),
										t.save(),
										t.transform(i[0], i[1], i[2], i[3], i[4], i[5]),
										this._renderObjects(t, e),
										t.restore(),
										!this.controlsAboveOverlay && this.interactive && this.drawControls(t),
										r && ((r.canvas = this), r.shouldCache(), (r._transformDone = !0), r.renderCache({ forClipping: !0 }), this.drawClipPathOnCanvas(t)),
										this._renderOverlay(t),
										this.controlsAboveOverlay && this.interactive && this.drawControls(t),
										this.fire('after:render', { ctx: t });
								},
								drawClipPathOnCanvas: function (t) {
									var e = this.viewportTransform,
										i = this.clipPath;
									t.save(),
										t.transform(e[0], e[1], e[2], e[3], e[4], e[5]),
										(t.globalCompositeOperation = 'destination-in'),
										i.transform(t),
										t.scale(1 / i.zoomX, 1 / i.zoomY),
										t.drawImage(i._cacheCanvas, -i.cacheTranslationX, -i.cacheTranslationY),
										t.restore();
								},
								_renderObjects: function (t, e) {
									var i, n;
									for (i = 0, n = e.length; i < n; ++i) e[i] && e[i].render(t);
								},
								_renderBackgroundOrOverlay: function (t, e) {
									var i = this[e + 'Color'],
										n = this[e + 'Image'],
										r = this.viewportTransform,
										o = this[e + 'Vpt'];
									if (i || n) {
										if (i) {
											t.save(),
												t.beginPath(),
												t.moveTo(0, 0),
												t.lineTo(this.width, 0),
												t.lineTo(this.width, this.height),
												t.lineTo(0, this.height),
												t.closePath(),
												(t.fillStyle = i.toLive ? i.toLive(t, this) : i),
												o && t.transform(r[0], r[1], r[2], r[3], r[4], r[5]),
												t.transform(1, 0, 0, 1, i.offsetX || 0, i.offsetY || 0);
											var s = i.gradientTransform || i.patternTransform;
											s && t.transform(s[0], s[1], s[2], s[3], s[4], s[5]), t.fill(), t.restore();
										}
										n && (t.save(), o && t.transform(r[0], r[1], r[2], r[3], r[4], r[5]), n.render(t), t.restore());
									}
								},
								_renderBackground: function (t) {
									this._renderBackgroundOrOverlay(t, 'background');
								},
								_renderOverlay: function (t) {
									this._renderBackgroundOrOverlay(t, 'overlay');
								},
								getCenter: function () {
									return { top: this.height / 2, left: this.width / 2 };
								},
								getCenterPoint: function () {
									return new n.Point(this.width / 2, this.height / 2);
								},
								centerObjectH: function (t) {
									return this._centerObject(t, new n.Point(this.getCenterPoint().x, t.getCenterPoint().y));
								},
								centerObjectV: function (t) {
									return this._centerObject(t, new n.Point(t.getCenterPoint().x, this.getCenterPoint().y));
								},
								centerObject: function (t) {
									var e = this.getCenterPoint();
									return this._centerObject(t, e);
								},
								viewportCenterObject: function (t) {
									var e = this.getVpCenter();
									return this._centerObject(t, e);
								},
								viewportCenterObjectH: function (t) {
									var e = this.getVpCenter();
									return this._centerObject(t, new n.Point(e.x, t.getCenterPoint().y)), this;
								},
								viewportCenterObjectV: function (t) {
									var e = this.getVpCenter();
									return this._centerObject(t, new n.Point(t.getCenterPoint().x, e.y));
								},
								getVpCenter: function () {
									var t = this.getCenterPoint(),
										e = s(this.viewportTransform);
									return o(t, e);
								},
								_centerObject: function (t, e) {
									return t.setPositionByOrigin(e, 'center', 'center'), t.setCoords(), this.renderOnAddRemove && this.requestRenderAll(), this;
								},
								toDatalessJSON: function (t) {
									return this.toDatalessObject(t);
								},
								toObject: function (t) {
									return this._toObjectMethod('toObject', t);
								},
								toDatalessObject: function (t) {
									return this._toObjectMethod('toDatalessObject', t);
								},
								_toObjectMethod: function (e, i) {
									var r = this.clipPath,
										o = { version: n.version, objects: this._toObjects(e, i) };
									return (
										r && !r.excludeFromExport && (o.clipPath = this._toObject(this.clipPath, e, i)),
										t(o, this.__serializeBgOverlay(e, i)),
										n.util.populateWithProperties(this, o, i),
										o
									);
								},
								_toObjects: function (t, e) {
									return this._objects
										.filter(function (t) {
											return !t.excludeFromExport;
										})
										.map(function (i) {
											return this._toObject(i, t, e);
										}, this);
								},
								_toObject: function (t, e, i) {
									var n;
									this.includeDefaultValues || ((n = t.includeDefaultValues), (t.includeDefaultValues = !1));
									var r = t[e](i);
									return this.includeDefaultValues || (t.includeDefaultValues = n), r;
								},
								__serializeBgOverlay: function (t, e) {
									var i = {},
										n = this.backgroundImage,
										r = this.overlayImage,
										o = this.backgroundColor,
										s = this.overlayColor;
									return (
										o && o.toObject ? o.excludeFromExport || (i.background = o.toObject(e)) : o && (i.background = o),
										s && s.toObject ? s.excludeFromExport || (i.overlay = s.toObject(e)) : s && (i.overlay = s),
										n && !n.excludeFromExport && (i.backgroundImage = this._toObject(n, t, e)),
										r && !r.excludeFromExport && (i.overlayImage = this._toObject(r, t, e)),
										i
									);
								},
								svgViewportTransformation: !0,
								toSVG: function (t, e) {
									t || (t = {}), (t.reviver = e);
									var i = [];
									return (
										this._setSVGPreamble(i, t),
										this._setSVGHeader(i, t),
										this.clipPath && i.push('<g clip-path="url(#' + this.clipPath.clipPathId + ')" >\n'),
										this._setSVGBgOverlayColor(i, 'background'),
										this._setSVGBgOverlayImage(i, 'backgroundImage', e),
										this._setSVGObjects(i, e),
										this.clipPath && i.push('</g>\n'),
										this._setSVGBgOverlayColor(i, 'overlay'),
										this._setSVGBgOverlayImage(i, 'overlayImage', e),
										i.push('</svg>'),
										i.join('')
									);
								},
								_setSVGPreamble: function (t, e) {
									e.suppressPreamble ||
										t.push(
											'<?xml version="1.0" encoding="',
											e.encoding || 'UTF-8',
											'" standalone="no" ?>\n',
											'<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" ',
											'"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\n'
										);
								},
								_setSVGHeader: function (t, e) {
									var i,
										o = e.width || this.width,
										s = e.height || this.height,
										a = 'viewBox="0 0 ' + this.width + ' ' + this.height + '" ',
										c = n.Object.NUM_FRACTION_DIGITS;
									e.viewBox
										? (a = 'viewBox="' + e.viewBox.x + ' ' + e.viewBox.y + ' ' + e.viewBox.width + ' ' + e.viewBox.height + '" ')
										: this.svgViewportTransformation &&
										  ((i = this.viewportTransform),
										  (a = 'viewBox="' + r(-i[4] / i[0], c) + ' ' + r(-i[5] / i[3], c) + ' ' + r(this.width / i[0], c) + ' ' + r(this.height / i[3], c) + '" ')),
										t.push(
											'<svg ',
											'xmlns="http://www.w3.org/2000/svg" ',
											'xmlns:xlink="http://www.w3.org/1999/xlink" ',
											'version="1.1" ',
											'width="',
											o,
											'" ',
											'height="',
											s,
											'" ',
											a,
											'xml:space="preserve">\n',
											'<desc>Created with Fabric.js ',
											n.version,
											'</desc>\n',
											'<defs>\n',
											this.createSVGFontFacesMarkup(),
											this.createSVGRefElementsMarkup(),
											this.createSVGClipPathMarkup(e),
											'</defs>\n'
										);
								},
								createSVGClipPathMarkup: function (t) {
									var e = this.clipPath;
									return e
										? ((e.clipPathId = 'CLIPPATH_' + n.Object.__uid++), '<clipPath id="' + e.clipPathId + '" >\n' + this.clipPath.toClipPathSVG(t.reviver) + '</clipPath>\n')
										: '';
								},
								createSVGRefElementsMarkup: function () {
									var t = this,
										e = ['background', 'overlay'].map(function (e) {
											var i = t[e + 'Color'];
											if (i && i.toLive) {
												var r = t[e + 'Vpt'],
													o = t.viewportTransform,
													s = { width: t.width / (r ? o[0] : 1), height: t.height / (r ? o[3] : 1) };
												return i.toSVG(s, { additionalTransform: r ? n.util.matrixToSVG(o) : '' });
											}
										});
									return e.join('');
								},
								createSVGFontFacesMarkup: function () {
									var t,
										e,
										i,
										r,
										o,
										s,
										a,
										c,
										h,
										l = '',
										u = {},
										f = n.fontPaths,
										d = [];
									for (
										this._objects.forEach(function t(e) {
											d.push(e), e._objects && e._objects.forEach(t);
										}),
											c = 0,
											h = d.length;
										c < h;
										c++
									)
										if (((t = d[c]), (e = t.fontFamily), -1 !== t.type.indexOf('text') && !u[e] && f[e] && ((u[e] = !0), t.styles)))
											for (o in ((i = t.styles), i)) for (a in ((r = i[o]), r)) (s = r[a]), (e = s.fontFamily), !u[e] && f[e] && (u[e] = !0);
									for (var p in u) l += ['\t\t@font-face {\n', "\t\t\tfont-family: '", p, "';\n", "\t\t\tsrc: url('", f[p], "');\n", '\t\t}\n'].join('');
									return l && (l = ['\t<style type="text/css">', '<![CDATA[\n', l, ']]>', '</style>\n'].join('')), l;
								},
								_setSVGObjects: function (t, e) {
									var i,
										n,
										r,
										o = this._objects;
									for (n = 0, r = o.length; n < r; n++) (i = o[n]), i.excludeFromExport || this._setSVGObject(t, i, e);
								},
								_setSVGObject: function (t, e, i) {
									t.push(e.toSVG(i));
								},
								_setSVGBgOverlayImage: function (t, e, i) {
									this[e] && !this[e].excludeFromExport && this[e].toSVG && t.push(this[e].toSVG(i));
								},
								_setSVGBgOverlayColor: function (t, e) {
									var i = this[e + 'Color'],
										r = this.viewportTransform,
										o = this.width,
										s = this.height;
									if (i)
										if (i.toLive) {
											var a = i.repeat,
												c = n.util.invertTransform(r),
												h = this[e + 'Vpt'],
												l = h ? n.util.matrixToSVG(c) : '';
											t.push(
												'<rect transform="' + l + ' translate(',
												o / 2,
												',',
												s / 2,
												')"',
												' x="',
												i.offsetX - o / 2,
												'" y="',
												i.offsetY - s / 2,
												'" ',
												'width="',
												'repeat-y' === a || 'no-repeat' === a ? i.source.width : o,
												'" height="',
												'repeat-x' === a || 'no-repeat' === a ? i.source.height : s,
												'" fill="url(#SVGID_' + i.id + ')"',
												'></rect>\n'
											);
										} else t.push('<rect x="0" y="0" width="100%" height="100%" ', 'fill="', i, '"', '></rect>\n');
								},
								sendToBack: function (t) {
									if (!t) return this;
									var e,
										n,
										r,
										o = this._activeObject;
									if (t === o && 'activeSelection' === t.type) for (r = o._objects, e = r.length; e--; ) (n = r[e]), i(this._objects, n), this._objects.unshift(n);
									else i(this._objects, t), this._objects.unshift(t);
									return this.renderOnAddRemove && this.requestRenderAll(), this;
								},
								bringToFront: function (t) {
									if (!t) return this;
									var e,
										n,
										r,
										o = this._activeObject;
									if (t === o && 'activeSelection' === t.type) for (r = o._objects, e = 0; e < r.length; e++) (n = r[e]), i(this._objects, n), this._objects.push(n);
									else i(this._objects, t), this._objects.push(t);
									return this.renderOnAddRemove && this.requestRenderAll(), this;
								},
								sendBackwards: function (t, e) {
									if (!t) return this;
									var n,
										r,
										o,
										s,
										a,
										c = this._activeObject,
										h = 0;
									if (t === c && 'activeSelection' === t.type)
										for (a = c._objects, n = 0; n < a.length; n++)
											(r = a[n]), (o = this._objects.indexOf(r)), o > 0 + h && ((s = o - 1), i(this._objects, r), this._objects.splice(s, 0, r)), h++;
									else (o = this._objects.indexOf(t)), 0 !== o && ((s = this._findNewLowerIndex(t, o, e)), i(this._objects, t), this._objects.splice(s, 0, t));
									return this.renderOnAddRemove && this.requestRenderAll(), this;
								},
								_findNewLowerIndex: function (t, e, i) {
									var n, r;
									if (i)
										for (n = e, r = e - 1; r >= 0; --r) {
											var o = t.intersectsWithObject(this._objects[r]) || t.isContainedWithinObject(this._objects[r]) || this._objects[r].isContainedWithinObject(t);
											if (o) {
												n = r;
												break;
											}
										}
									else n = e - 1;
									return n;
								},
								bringForward: function (t, e) {
									if (!t) return this;
									var n,
										r,
										o,
										s,
										a,
										c = this._activeObject,
										h = 0;
									if (t === c && 'activeSelection' === t.type)
										for (a = c._objects, n = a.length; n--; )
											(r = a[n]), (o = this._objects.indexOf(r)), o < this._objects.length - 1 - h && ((s = o + 1), i(this._objects, r), this._objects.splice(s, 0, r)), h++;
									else (o = this._objects.indexOf(t)), o !== this._objects.length - 1 && ((s = this._findNewUpperIndex(t, o, e)), i(this._objects, t), this._objects.splice(s, 0, t));
									return this.renderOnAddRemove && this.requestRenderAll(), this;
								},
								_findNewUpperIndex: function (t, e, i) {
									var n, r, o;
									if (i)
										for (n = e, r = e + 1, o = this._objects.length; r < o; ++r) {
											var s = t.intersectsWithObject(this._objects[r]) || t.isContainedWithinObject(this._objects[r]) || this._objects[r].isContainedWithinObject(t);
											if (s) {
												n = r;
												break;
											}
										}
									else n = e + 1;
									return n;
								},
								moveTo: function (t, e) {
									return i(this._objects, t), this._objects.splice(e, 0, t), this.renderOnAddRemove && this.requestRenderAll();
								},
								dispose: function () {
									return (
										this.isRendering && (n.util.cancelAnimFrame(this.isRendering), (this.isRendering = 0)),
										this.forEachObject(function (t) {
											t.dispose && t.dispose();
										}),
										(this._objects = []),
										this.backgroundImage && this.backgroundImage.dispose && this.backgroundImage.dispose(),
										(this.backgroundImage = null),
										this.overlayImage && this.overlayImage.dispose && this.overlayImage.dispose(),
										(this.overlayImage = null),
										(this._iTextInstances = null),
										(this.contextContainer = null),
										this.lowerCanvasEl.classList.remove('lower-canvas'),
										n.util.setStyle(this.lowerCanvasEl, this._originalCanvasStyle),
										delete this._originalCanvasStyle,
										this.lowerCanvasEl.setAttribute('width', this.width),
										this.lowerCanvasEl.setAttribute('height', this.height),
										n.util.cleanUpJsdomNode(this.lowerCanvasEl),
										(this.lowerCanvasEl = void 0),
										this
									);
								},
								toString: function () {
									return '#<fabric.Canvas (' + this.complexity() + '): { objects: ' + this._objects.length + ' }>';
								}
							})),
								t(n.StaticCanvas.prototype, n.Observable),
								t(n.StaticCanvas.prototype, n.Collection),
								t(n.StaticCanvas.prototype, n.DataURLExporter),
								t(n.StaticCanvas, {
									EMPTY_JSON: '{"objects": [], "background": "white"}',
									supports: function (t) {
										var e = c();
										if (!e || !e.getContext) return null;
										var i = e.getContext('2d');
										if (!i) return null;
										switch (t) {
											case 'setLineDash':
												return 'undefined' !== typeof i.setLineDash;
											default:
												return null;
										}
									}
								}),
								(n.StaticCanvas.prototype.toJSON = n.StaticCanvas.prototype.toObject),
								n.isLikelyNode &&
									((n.StaticCanvas.prototype.createPNGStream = function () {
										var t = a(this.lowerCanvasEl);
										return t && t.createPNGStream();
									}),
									(n.StaticCanvas.prototype.createJPEGStream = function (t) {
										var e = a(this.lowerCanvasEl);
										return e && e.createJPEGStream(t);
									}));
						}
					})(),
					(n.BaseBrush = n.util.createClass({
						color: 'rgb(0, 0, 0)',
						width: 1,
						shadow: null,
						strokeLineCap: 'round',
						strokeLineJoin: 'round',
						strokeMiterLimit: 10,
						strokeDashArray: null,
						limitedToCanvasSize: !1,
						_setBrushStyles: function (t) {
							(t.strokeStyle = this.color),
								(t.lineWidth = this.width),
								(t.lineCap = this.strokeLineCap),
								(t.miterLimit = this.strokeMiterLimit),
								(t.lineJoin = this.strokeLineJoin),
								t.setLineDash(this.strokeDashArray || []);
						},
						_saveAndTransform: function (t) {
							var e = this.canvas.viewportTransform;
							t.save(), t.transform(e[0], e[1], e[2], e[3], e[4], e[5]);
						},
						_setShadow: function () {
							if (this.shadow) {
								var t = this.canvas,
									e = this.shadow,
									i = t.contextTop,
									r = t.getZoom();
								t && t._isRetinaScaling() && (r *= n.devicePixelRatio),
									(i.shadowColor = e.color),
									(i.shadowBlur = e.blur * r),
									(i.shadowOffsetX = e.offsetX * r),
									(i.shadowOffsetY = e.offsetY * r);
							}
						},
						needsFullRender: function () {
							var t = new n.Color(this.color);
							return t.getAlpha() < 1 || !!this.shadow;
						},
						_resetShadow: function () {
							var t = this.canvas.contextTop;
							(t.shadowColor = ''), (t.shadowBlur = t.shadowOffsetX = t.shadowOffsetY = 0);
						},
						_isOutSideCanvas: function (t) {
							return t.x < 0 || t.x > this.canvas.getWidth() || t.y < 0 || t.y > this.canvas.getHeight();
						}
					})),
					(function () {
						n.PencilBrush = n.util.createClass(n.BaseBrush, {
							decimate: 0.4,
							drawStraightLine: !1,
							straightLineKey: 'shiftKey',
							initialize: function (t) {
								(this.canvas = t), (this._points = []);
							},
							needsFullRender: function () {
								return this.callSuper('needsFullRender') || this._hasStraightLine;
							},
							_drawSegment: function (t, e, i) {
								var n = e.midPointFrom(i);
								return t.quadraticCurveTo(e.x, e.y, n.x, n.y), n;
							},
							onMouseDown: function (t, e) {
								this.canvas._isMainEvent(e.e) && ((this.drawStraightLine = e.e[this.straightLineKey]), this._prepareForDrawing(t), this._captureDrawingPath(t), this._render());
							},
							onMouseMove: function (t, e) {
								if (
									this.canvas._isMainEvent(e.e) &&
									((this.drawStraightLine = e.e[this.straightLineKey]),
									(!0 !== this.limitedToCanvasSize || !this._isOutSideCanvas(t)) && this._captureDrawingPath(t) && this._points.length > 1)
								)
									if (this.needsFullRender()) this.canvas.clearContext(this.canvas.contextTop), this._render();
									else {
										var i = this._points,
											n = i.length,
											r = this.canvas.contextTop;
										this._saveAndTransform(r),
											this.oldEnd && (r.beginPath(), r.moveTo(this.oldEnd.x, this.oldEnd.y)),
											(this.oldEnd = this._drawSegment(r, i[n - 2], i[n - 1], !0)),
											r.stroke(),
											r.restore();
									}
							},
							onMouseUp: function (t) {
								return !this.canvas._isMainEvent(t.e) || ((this.drawStraightLine = !1), (this.oldEnd = void 0), this._finalizeAndAddPath(), !1);
							},
							_prepareForDrawing: function (t) {
								var e = new n.Point(t.x, t.y);
								this._reset(), this._addPoint(e), this.canvas.contextTop.moveTo(e.x, e.y);
							},
							_addPoint: function (t) {
								return (
									!(this._points.length > 1 && t.eq(this._points[this._points.length - 1])) &&
									(this.drawStraightLine && this._points.length > 1 && ((this._hasStraightLine = !0), this._points.pop()), this._points.push(t), !0)
								);
							},
							_reset: function () {
								(this._points = []), this._setBrushStyles(this.canvas.contextTop), this._setShadow(), (this._hasStraightLine = !1);
							},
							_captureDrawingPath: function (t) {
								var e = new n.Point(t.x, t.y);
								return this._addPoint(e);
							},
							_render: function (t) {
								var e,
									i,
									r = this._points[0],
									o = this._points[1];
								if (((t = t || this.canvas.contextTop), this._saveAndTransform(t), t.beginPath(), 2 === this._points.length && r.x === o.x && r.y === o.y)) {
									var s = this.width / 1e3;
									(r = new n.Point(r.x, r.y)), (o = new n.Point(o.x, o.y)), (r.x -= s), (o.x += s);
								}
								for (t.moveTo(r.x, r.y), e = 1, i = this._points.length; e < i; e++) this._drawSegment(t, r, o), (r = this._points[e]), (o = this._points[e + 1]);
								t.lineTo(r.x, r.y), t.stroke(), t.restore();
							},
							convertPointsToSVGPath: function (t) {
								var e = this.width / 1e3;
								return n.util.getSmoothPathFromPoints(t, e);
							},
							_isEmptySVGPath: function (t) {
								var e = n.util.joinPath(t);
								return 'M 0 0 Q 0 0 0 0 L 0 0' === e;
							},
							createPath: function (t) {
								var e = new n.Path(t, {
									fill: null,
									stroke: this.color,
									strokeWidth: this.width,
									strokeLineCap: this.strokeLineCap,
									strokeMiterLimit: this.strokeMiterLimit,
									strokeLineJoin: this.strokeLineJoin,
									strokeDashArray: this.strokeDashArray
								});
								return this.shadow && ((this.shadow.affectStroke = !0), (e.shadow = new n.Shadow(this.shadow))), e;
							},
							decimatePoints: function (t, e) {
								if (t.length <= 2) return t;
								var i,
									n,
									r = this.canvas.getZoom(),
									o = Math.pow(e / r, 2),
									s = t.length - 1,
									a = t[0],
									c = [a];
								for (i = 1; i < s - 1; i++) (n = Math.pow(a.x - t[i].x, 2) + Math.pow(a.y - t[i].y, 2)), n >= o && ((a = t[i]), c.push(a));
								return c.push(t[s]), c;
							},
							_finalizeAndAddPath: function () {
								var t = this.canvas.contextTop;
								t.closePath(), this.decimate && (this._points = this.decimatePoints(this._points, this.decimate));
								var e = this.convertPointsToSVGPath(this._points);
								if (this._isEmptySVGPath(e)) this.canvas.requestRenderAll();
								else {
									var i = this.createPath(e);
									this.canvas.clearContext(this.canvas.contextTop),
										this.canvas.fire('before:path:created', { path: i }),
										this.canvas.add(i),
										this.canvas.requestRenderAll(),
										i.setCoords(),
										this._resetShadow(),
										this.canvas.fire('path:created', { path: i });
								}
							}
						});
					})(),
					(n.CircleBrush = n.util.createClass(n.BaseBrush, {
						width: 10,
						initialize: function (t) {
							(this.canvas = t), (this.points = []);
						},
						drawDot: function (t) {
							var e = this.addPoint(t),
								i = this.canvas.contextTop;
							this._saveAndTransform(i), this.dot(i, e), i.restore();
						},
						dot: function (t, e) {
							(t.fillStyle = e.fill), t.beginPath(), t.arc(e.x, e.y, e.radius, 0, 2 * Math.PI, !1), t.closePath(), t.fill();
						},
						onMouseDown: function (t) {
							(this.points.length = 0), this.canvas.clearContext(this.canvas.contextTop), this._setShadow(), this.drawDot(t);
						},
						_render: function () {
							var t,
								e,
								i = this.canvas.contextTop,
								n = this.points;
							for (this._saveAndTransform(i), t = 0, e = n.length; t < e; t++) this.dot(i, n[t]);
							i.restore();
						},
						onMouseMove: function (t) {
							(!0 === this.limitedToCanvasSize && this._isOutSideCanvas(t)) ||
								(this.needsFullRender() ? (this.canvas.clearContext(this.canvas.contextTop), this.addPoint(t), this._render()) : this.drawDot(t));
						},
						onMouseUp: function () {
							var t,
								e,
								i = this.canvas.renderOnAddRemove;
							this.canvas.renderOnAddRemove = !1;
							var r = [];
							for (t = 0, e = this.points.length; t < e; t++) {
								var o = this.points[t],
									s = new n.Circle({ radius: o.radius, left: o.x, top: o.y, originX: 'center', originY: 'center', fill: o.fill });
								this.shadow && (s.shadow = new n.Shadow(this.shadow)), r.push(s);
							}
							var a = new n.Group(r);
							(a.canvas = this.canvas),
								this.canvas.fire('before:path:created', { path: a }),
								this.canvas.add(a),
								this.canvas.fire('path:created', { path: a }),
								this.canvas.clearContext(this.canvas.contextTop),
								this._resetShadow(),
								(this.canvas.renderOnAddRemove = i),
								this.canvas.requestRenderAll();
						},
						addPoint: function (t) {
							var e = new n.Point(t.x, t.y),
								i = n.util.getRandomInt(Math.max(0, this.width - 20), this.width + 20) / 2,
								r = new n.Color(this.color).setAlpha(n.util.getRandomInt(0, 100) / 100).toRgba();
							return (e.radius = i), (e.fill = r), this.points.push(e), e;
						}
					})),
					(n.SprayBrush = n.util.createClass(n.BaseBrush, {
						width: 10,
						density: 20,
						dotWidth: 1,
						dotWidthVariance: 1,
						randomOpacity: !1,
						optimizeOverlapping: !0,
						initialize: function (t) {
							(this.canvas = t), (this.sprayChunks = []);
						},
						onMouseDown: function (t) {
							(this.sprayChunks.length = 0), this.canvas.clearContext(this.canvas.contextTop), this._setShadow(), this.addSprayChunk(t), this.render(this.sprayChunkPoints);
						},
						onMouseMove: function (t) {
							(!0 === this.limitedToCanvasSize && this._isOutSideCanvas(t)) || (this.addSprayChunk(t), this.render(this.sprayChunkPoints));
						},
						onMouseUp: function () {
							var t = this.canvas.renderOnAddRemove;
							this.canvas.renderOnAddRemove = !1;
							for (var e = [], i = 0, r = this.sprayChunks.length; i < r; i++)
								for (var o = this.sprayChunks[i], s = 0, a = o.length; s < a; s++) {
									var c = new n.Rect({ width: o[s].width, height: o[s].width, left: o[s].x + 1, top: o[s].y + 1, originX: 'center', originY: 'center', fill: this.color });
									e.push(c);
								}
							this.optimizeOverlapping && (e = this._getOptimizedRects(e));
							var h = new n.Group(e);
							this.shadow && h.set('shadow', new n.Shadow(this.shadow)),
								this.canvas.fire('before:path:created', { path: h }),
								this.canvas.add(h),
								this.canvas.fire('path:created', { path: h }),
								this.canvas.clearContext(this.canvas.contextTop),
								this._resetShadow(),
								(this.canvas.renderOnAddRemove = t),
								this.canvas.requestRenderAll();
						},
						_getOptimizedRects: function (t) {
							var e,
								i,
								n,
								r = {};
							for (i = 0, n = t.length; i < n; i++) (e = t[i].left + '' + t[i].top), r[e] || (r[e] = t[i]);
							var o = [];
							for (e in r) o.push(r[e]);
							return o;
						},
						render: function (t) {
							var e,
								i,
								n = this.canvas.contextTop;
							for (n.fillStyle = this.color, this._saveAndTransform(n), e = 0, i = t.length; e < i; e++) {
								var r = t[e];
								'undefined' !== typeof r.opacity && (n.globalAlpha = r.opacity), n.fillRect(r.x, r.y, r.width, r.width);
							}
							n.restore();
						},
						_render: function () {
							var t,
								e,
								i = this.canvas.contextTop;
							for (i.fillStyle = this.color, this._saveAndTransform(i), t = 0, e = this.sprayChunks.length; t < e; t++) this.render(this.sprayChunks[t]);
							i.restore();
						},
						addSprayChunk: function (t) {
							this.sprayChunkPoints = [];
							var e,
								i,
								r,
								o,
								s = this.width / 2;
							for (o = 0; o < this.density; o++) {
								(e = n.util.getRandomInt(t.x - s, t.x + s)),
									(i = n.util.getRandomInt(t.y - s, t.y + s)),
									(r = this.dotWidthVariance ? n.util.getRandomInt(Math.max(1, this.dotWidth - this.dotWidthVariance), this.dotWidth + this.dotWidthVariance) : this.dotWidth);
								var a = new n.Point(e, i);
								(a.width = r), this.randomOpacity && (a.opacity = n.util.getRandomInt(0, 100) / 100), this.sprayChunkPoints.push(a);
							}
							this.sprayChunks.push(this.sprayChunkPoints);
						}
					})),
					(n.PatternBrush = n.util.createClass(n.PencilBrush, {
						getPatternSrc: function () {
							var t = 20,
								e = 5,
								i = n.util.createCanvasElement(),
								r = i.getContext('2d');
							return (i.width = i.height = t + e), (r.fillStyle = this.color), r.beginPath(), r.arc(t / 2, t / 2, t / 2, 0, 2 * Math.PI, !1), r.closePath(), r.fill(), i;
						},
						getPatternSrcFunction: function () {
							return String(this.getPatternSrc).replace('this.color', '"' + this.color + '"');
						},
						getPattern: function (t) {
							return t.createPattern(this.source || this.getPatternSrc(), 'repeat');
						},
						_setBrushStyles: function (t) {
							this.callSuper('_setBrushStyles', t), (t.strokeStyle = this.getPattern(t));
						},
						createPath: function (t) {
							var e = this.callSuper('createPath', t),
								i = e._getLeftTopCoords().scalarAdd(e.strokeWidth / 2);
							return (e.stroke = new n.Pattern({ source: this.source || this.getPatternSrcFunction(), offsetX: -i.x, offsetY: -i.y })), e;
						}
					})),
					(function () {
						var t = n.util.getPointer,
							e = n.util.degreesToRadians,
							i = n.util.isTouchEvent;
						for (var r in ((n.Canvas = n.util.createClass(n.StaticCanvas, {
							initialize: function (t, e) {
								e || (e = {}),
									(this.renderAndResetBound = this.renderAndReset.bind(this)),
									(this.requestRenderAllBound = this.requestRenderAll.bind(this)),
									this._initStatic(t, e),
									this._initInteractive(),
									this._createCacheCanvas();
							},
							uniformScaling: !0,
							uniScaleKey: 'shiftKey',
							centeredScaling: !1,
							centeredRotation: !1,
							centeredKey: 'altKey',
							altActionKey: 'shiftKey',
							interactive: !0,
							selection: !0,
							selectionKey: 'shiftKey',
							altSelectionKey: null,
							selectionColor: 'rgba(92,146,236,0.2)',
							selectionDashArray: [],
							selectionBorderColor: 'rgba(255, 255, 255, 0.3)',
							selectionLineWidth: 1,
							selectionFullyContained: !1,
							hoverCursor: 'move',
							moveCursor: 'move',
							defaultCursor: 'default',
							freeDrawingCursor: 'crosshair',
							notAllowedCursor: 'not-allowed',
							containerClass: 'canvas-container',
							perPixelTargetFind: !1,
							targetFindTolerance: 0,
							skipTargetFind: !1,
							isDrawingMode: !1,
							preserveObjectStacking: !1,
							snapAngle: 0,
							snapThreshold: null,
							stopContextMenu: !1,
							fireRightClick: !1,
							fireMiddleClick: !1,
							targets: [],
							enablePointerEvents: !1,
							_hoveredTarget: null,
							_hoveredTargets: [],
							_initInteractive: function () {
								(this._currentTransform = null),
									(this._groupSelector = null),
									this._initWrapperElement(),
									this._createUpperCanvas(),
									this._initEventListeners(),
									this._initRetinaScaling(),
									(this.freeDrawingBrush = n.PencilBrush && new n.PencilBrush(this)),
									this.calcOffset();
							},
							_chooseObjectsToRender: function () {
								var t,
									e,
									i,
									n = this.getActiveObjects();
								if (n.length > 0 && !this.preserveObjectStacking) {
									(e = []), (i = []);
									for (var r = 0, o = this._objects.length; r < o; r++) (t = this._objects[r]), -1 === n.indexOf(t) ? e.push(t) : i.push(t);
									n.length > 1 && (this._activeObject._objects = i), e.push.apply(e, i);
								} else e = this._objects;
								return e;
							},
							renderAll: function () {
								!this.contextTopDirty || this._groupSelector || this.isDrawingMode || (this.clearContext(this.contextTop), (this.contextTopDirty = !1)),
									this.hasLostContext && (this.renderTopLayer(this.contextTop), (this.hasLostContext = !1));
								var t = this.contextContainer;
								return this.renderCanvas(t, this._chooseObjectsToRender()), this;
							},
							renderTopLayer: function (t) {
								t.save(),
									this.isDrawingMode && this._isCurrentlyDrawing && (this.freeDrawingBrush && this.freeDrawingBrush._render(), (this.contextTopDirty = !0)),
									this.selection && this._groupSelector && (this._drawSelection(t), (this.contextTopDirty = !0)),
									t.restore();
							},
							renderTop: function () {
								var t = this.contextTop;
								return this.clearContext(t), this.renderTopLayer(t), this.fire('after:render'), this;
							},
							_normalizePointer: function (t, e) {
								var i = t.calcTransformMatrix(),
									r = n.util.invertTransform(i),
									o = this.restorePointerVpt(e);
								return n.util.transformPoint(o, r);
							},
							isTargetTransparent: function (t, e, i) {
								if (t.shouldCache() && t._cacheCanvas && t !== this._activeObject) {
									var r = this._normalizePointer(t, { x: e, y: i }),
										o = Math.max(t.cacheTranslationX + r.x * t.zoomX, 0),
										s = Math.max(t.cacheTranslationY + r.y * t.zoomY, 0),
										a = n.util.isTransparent(t._cacheContext, Math.round(o), Math.round(s), this.targetFindTolerance);
									return a;
								}
								var c = this.contextCache,
									h = t.selectionBackgroundColor,
									l = this.viewportTransform;
								(t.selectionBackgroundColor = ''),
									this.clearContext(c),
									c.save(),
									c.transform(l[0], l[1], l[2], l[3], l[4], l[5]),
									t.render(c),
									c.restore(),
									(t.selectionBackgroundColor = h);
								a = n.util.isTransparent(c, e, i, this.targetFindTolerance);
								return a;
							},
							_isSelectionKeyPressed: function (t) {
								var e = !1;
								return (
									(e = Array.isArray(this.selectionKey)
										? !!this.selectionKey.find(function (e) {
												return !0 === t[e];
										  })
										: t[this.selectionKey]),
									e
								);
							},
							_shouldClearSelection: function (t, e) {
								var i = this.getActiveObjects(),
									n = this._activeObject;
								return !e || (e && n && i.length > 1 && -1 === i.indexOf(e) && n !== e && !this._isSelectionKeyPressed(t)) || (e && !e.evented) || (e && !e.selectable && n && n !== e);
							},
							_shouldCenterTransform: function (t, e, i) {
								var n;
								if (t)
									return (
										'scale' === e || 'scaleX' === e || 'scaleY' === e || 'resizing' === e
											? (n = this.centeredScaling || t.centeredScaling)
											: 'rotate' === e && (n = this.centeredRotation || t.centeredRotation),
										n ? !i : i
									);
							},
							_getOriginFromCorner: function (t, e) {
								var i = { x: t.originX, y: t.originY };
								return (
									'ml' === e || 'tl' === e || 'bl' === e ? (i.x = 'right') : ('mr' !== e && 'tr' !== e && 'br' !== e) || (i.x = 'left'),
									'tl' === e || 'mt' === e || 'tr' === e ? (i.y = 'bottom') : ('bl' !== e && 'mb' !== e && 'br' !== e) || (i.y = 'top'),
									i
								);
							},
							_getActionFromCorner: function (t, e, i, n) {
								if (!e || !t) return 'drag';
								var r = n.controls[e];
								return r.getActionName(i, r, n);
							},
							_setupCurrentTransform: function (t, i, r) {
								if (i) {
									var o = this.getPointer(t),
										s = i.__corner,
										a = i.controls[s],
										c = r && s ? a.getActionHandler(t, i, a) : n.controlsUtils.dragHandler,
										h = this._getActionFromCorner(r, s, t, i),
										l = this._getOriginFromCorner(i, s),
										u = t[this.centeredKey],
										f = {
											target: i,
											action: h,
											actionHandler: c,
											corner: s,
											scaleX: i.scaleX,
											scaleY: i.scaleY,
											skewX: i.skewX,
											skewY: i.skewY,
											offsetX: o.x - i.left,
											offsetY: o.y - i.top,
											originX: l.x,
											originY: l.y,
											ex: o.x,
											ey: o.y,
											lastX: o.x,
											lastY: o.y,
											theta: e(i.angle),
											width: i.width * i.scaleX,
											shiftKey: t.shiftKey,
											altKey: u,
											original: n.util.saveObjectTransform(i)
										};
									this._shouldCenterTransform(i, h, u) && ((f.originX = 'center'), (f.originY = 'center')),
										(f.original.originX = l.x),
										(f.original.originY = l.y),
										(this._currentTransform = f),
										this._beforeTransform(t);
								}
							},
							setCursor: function (t) {
								this.upperCanvasEl.style.cursor = t;
							},
							_drawSelection: function (t) {
								var e = this._groupSelector,
									i = new n.Point(e.ex, e.ey),
									r = n.util.transformPoint(i, this.viewportTransform),
									o = new n.Point(e.ex + e.left, e.ey + e.top),
									s = n.util.transformPoint(o, this.viewportTransform),
									a = Math.min(r.x, s.x),
									c = Math.min(r.y, s.y),
									h = Math.max(r.x, s.x),
									l = Math.max(r.y, s.y),
									u = this.selectionLineWidth / 2;
								this.selectionColor && ((t.fillStyle = this.selectionColor), t.fillRect(a, c, h - a, l - c)),
									this.selectionLineWidth &&
										this.selectionBorderColor &&
										((t.lineWidth = this.selectionLineWidth),
										(t.strokeStyle = this.selectionBorderColor),
										(a += u),
										(c += u),
										(h -= u),
										(l -= u),
										n.Object.prototype._setLineDash.call(this, t, this.selectionDashArray),
										t.strokeRect(a, c, h - a, l - c));
							},
							findTarget: function (t, e) {
								if (!this.skipTargetFind) {
									var n,
										r,
										o = !0,
										s = this.getPointer(t, o),
										a = this._activeObject,
										c = this.getActiveObjects(),
										h = i(t),
										l = (c.length > 1 && !e) || 1 === c.length;
									if (((this.targets = []), l && a._findTargetCorner(s, h))) return a;
									if (c.length > 1 && !e && a === this._searchPossibleTargets([a], s)) return a;
									if (1 === c.length && a === this._searchPossibleTargets([a], s)) {
										if (!this.preserveObjectStacking) return a;
										(n = a), (r = this.targets), (this.targets = []);
									}
									var u = this._searchPossibleTargets(this._objects, s);
									return t[this.altSelectionKey] && u && n && u !== n && ((u = n), (this.targets = r)), u;
								}
							},
							_checkTarget: function (t, e, i) {
								if (e && e.visible && e.evented && e.containsPoint(t)) {
									if ((!this.perPixelTargetFind && !e.perPixelTargetFind) || e.isEditing) return !0;
									var n = this.isTargetTransparent(e, i.x, i.y);
									if (!n) return !0;
								}
							},
							_searchPossibleTargets: function (t, e) {
								var i,
									r,
									o = t.length;
								while (o--) {
									var s = t[o],
										a = s.group ? this._normalizePointer(s.group, e) : e;
									if (this._checkTarget(a, s, e)) {
										(i = t[o]), i.subTargetCheck && i instanceof n.Group && ((r = this._searchPossibleTargets(i._objects, e)), r && this.targets.push(r));
										break;
									}
								}
								return i;
							},
							restorePointerVpt: function (t) {
								return n.util.transformPoint(t, n.util.invertTransform(this.viewportTransform));
							},
							getPointer: function (e, i) {
								if (this._absolutePointer && !i) return this._absolutePointer;
								if (this._pointer && i) return this._pointer;
								var n,
									r = t(e),
									o = this.upperCanvasEl,
									s = o.getBoundingClientRect(),
									a = s.width || 0,
									c = s.height || 0;
								(a && c) || ('top' in s && 'bottom' in s && (c = Math.abs(s.top - s.bottom)), 'right' in s && 'left' in s && (a = Math.abs(s.right - s.left))),
									this.calcOffset(),
									(r.x = r.x - this._offset.left),
									(r.y = r.y - this._offset.top),
									i || (r = this.restorePointerVpt(r));
								var h = this.getRetinaScaling();
								return (
									1 !== h && ((r.x /= h), (r.y /= h)),
									(n = 0 === a || 0 === c ? { width: 1, height: 1 } : { width: o.width / a, height: o.height / c }),
									{ x: r.x * n.width, y: r.y * n.height }
								);
							},
							_createUpperCanvas: function () {
								var t = this.lowerCanvasEl.className.replace(/\s*lower-canvas\s*/, ''),
									e = this.lowerCanvasEl,
									i = this.upperCanvasEl;
								i ? (i.className = '') : ((i = this._createCanvasElement()), (this.upperCanvasEl = i)),
									n.util.addClass(i, 'upper-canvas ' + t),
									this.wrapperEl.appendChild(i),
									this._copyCanvasStyle(e, i),
									this._applyCanvasStyle(i),
									(this.contextTop = i.getContext('2d'));
							},
							getTopContext: function () {
								return this.contextTop;
							},
							_createCacheCanvas: function () {
								(this.cacheCanvasEl = this._createCanvasElement()),
									this.cacheCanvasEl.setAttribute('width', this.width),
									this.cacheCanvasEl.setAttribute('height', this.height),
									(this.contextCache = this.cacheCanvasEl.getContext('2d'));
							},
							_initWrapperElement: function () {
								(this.wrapperEl = n.util.wrapElement(this.lowerCanvasEl, 'div', { class: this.containerClass })),
									n.util.setStyle(this.wrapperEl, { width: this.width + 'px', height: this.height + 'px', position: 'relative' }),
									n.util.makeElementUnselectable(this.wrapperEl);
							},
							_applyCanvasStyle: function (t) {
								var e = this.width || t.width,
									i = this.height || t.height;
								n.util.setStyle(t, {
									position: 'absolute',
									width: e + 'px',
									height: i + 'px',
									left: 0,
									top: 0,
									'touch-action': this.allowTouchScrolling ? 'manipulation' : 'none',
									'-ms-touch-action': this.allowTouchScrolling ? 'manipulation' : 'none'
								}),
									(t.width = e),
									(t.height = i),
									n.util.makeElementUnselectable(t);
							},
							_copyCanvasStyle: function (t, e) {
								e.style.cssText = t.style.cssText;
							},
							getSelectionContext: function () {
								return this.contextTop;
							},
							getSelectionElement: function () {
								return this.upperCanvasEl;
							},
							getActiveObject: function () {
								return this._activeObject;
							},
							getActiveObjects: function () {
								var t = this._activeObject;
								return t ? ('activeSelection' === t.type && t._objects ? t._objects.slice(0) : [t]) : [];
							},
							_onObjectRemoved: function (t) {
								t === this._activeObject &&
									(this.fire('before:selection:cleared', { target: t }), this._discardActiveObject(), this.fire('selection:cleared', { target: t }), t.fire('deselected')),
									t === this._hoveredTarget && ((this._hoveredTarget = null), (this._hoveredTargets = [])),
									this.callSuper('_onObjectRemoved', t);
							},
							_fireSelectionEvents: function (t, e) {
								var i = !1,
									n = this.getActiveObjects(),
									r = [],
									o = [];
								t.forEach(function (t) {
									-1 === n.indexOf(t) && ((i = !0), t.fire('deselected', { e: e, target: t }), o.push(t));
								}),
									n.forEach(function (n) {
										-1 === t.indexOf(n) && ((i = !0), n.fire('selected', { e: e, target: n }), r.push(n));
									}),
									t.length > 0 && n.length > 0
										? i && this.fire('selection:updated', { e: e, selected: r, deselected: o })
										: n.length > 0
										? this.fire('selection:created', { e: e, selected: r })
										: t.length > 0 && this.fire('selection:cleared', { e: e, deselected: o });
							},
							setActiveObject: function (t, e) {
								var i = this.getActiveObjects();
								return this._setActiveObject(t, e), this._fireSelectionEvents(i, e), this;
							},
							_setActiveObject: function (t, e) {
								return this._activeObject !== t && !!this._discardActiveObject(e, t) && !t.onSelect({ e: e }) && ((this._activeObject = t), !0);
							},
							_discardActiveObject: function (t, e) {
								var i = this._activeObject;
								if (i) {
									if (i.onDeselect({ e: t, object: e })) return !1;
									this._activeObject = null;
								}
								return !0;
							},
							discardActiveObject: function (t) {
								var e = this.getActiveObjects(),
									i = this.getActiveObject();
								return e.length && this.fire('before:selection:cleared', { target: i, e: t }), this._discardActiveObject(t), this._fireSelectionEvents(e, t), this;
							},
							dispose: function () {
								var t = this.wrapperEl;
								return (
									this.removeListeners(),
									t.removeChild(this.upperCanvasEl),
									t.removeChild(this.lowerCanvasEl),
									(this.contextCache = null),
									(this.contextTop = null),
									['upperCanvasEl', 'cacheCanvasEl'].forEach(
										function (t) {
											n.util.cleanUpJsdomNode(this[t]), (this[t] = void 0);
										}.bind(this)
									),
									t.parentNode && t.parentNode.replaceChild(this.lowerCanvasEl, this.wrapperEl),
									delete this.wrapperEl,
									n.StaticCanvas.prototype.dispose.call(this),
									this
								);
							},
							clear: function () {
								return this.discardActiveObject(), this.clearContext(this.contextTop), this.callSuper('clear');
							},
							drawControls: function (t) {
								var e = this._activeObject;
								e && e._renderControls(t);
							},
							_toObject: function (t, e, i) {
								var n = this._realizeGroupTransformOnObject(t),
									r = this.callSuper('_toObject', t, e, i);
								return this._unwindGroupTransformOnObject(t, n), r;
							},
							_realizeGroupTransformOnObject: function (t) {
								if (t.group && 'activeSelection' === t.group.type && this._activeObject === t.group) {
									var e = ['angle', 'flipX', 'flipY', 'left', 'scaleX', 'scaleY', 'skewX', 'skewY', 'top'],
										i = {};
									return (
										e.forEach(function (e) {
											i[e] = t[e];
										}),
										n.util.addTransformToObject(t, this._activeObject.calcOwnMatrix()),
										i
									);
								}
								return null;
							},
							_unwindGroupTransformOnObject: function (t, e) {
								e && t.set(e);
							},
							_setSVGObject: function (t, e, i) {
								var n = this._realizeGroupTransformOnObject(e);
								this.callSuper('_setSVGObject', t, e, i), this._unwindGroupTransformOnObject(e, n);
							},
							setViewportTransform: function (t) {
								this.renderOnAddRemove && this._activeObject && this._activeObject.isEditing && this._activeObject.clearContextTop(),
									n.StaticCanvas.prototype.setViewportTransform.call(this, t);
							}
						})),
						n.StaticCanvas))
							'prototype' !== r && (n.Canvas[r] = n.StaticCanvas[r]);
					})(),
					(function () {
						var t = n.util.addListener,
							e = n.util.removeListener,
							i = 3,
							o = 2,
							s = 1,
							a = { passive: !1 };
						function c(t, e) {
							return t.button && t.button === e - 1;
						}
						n.util.object.extend(n.Canvas.prototype, {
							mainTouchId: null,
							_initEventListeners: function () {
								this.removeListeners(), this._bindEvents(), this.addOrRemove(t, 'add');
							},
							_getEventPrefix: function () {
								return this.enablePointerEvents ? 'pointer' : 'mouse';
							},
							addOrRemove: function (t, e) {
								var i = this.upperCanvasEl,
									o = this._getEventPrefix();
								t(n.window, 'resize', this._onResize),
									t(i, o + 'down', this._onMouseDown),
									t(i, o + 'move', this._onMouseMove, a),
									t(i, o + 'out', this._onMouseOut),
									t(i, o + 'enter', this._onMouseEnter),
									t(i, 'wheel', this._onMouseWheel),
									t(i, 'contextmenu', this._onContextMenu),
									t(i, 'dblclick', this._onDoubleClick),
									t(i, 'dragover', this._onDragOver),
									t(i, 'dragenter', this._onDragEnter),
									t(i, 'dragleave', this._onDragLeave),
									t(i, 'drop', this._onDrop),
									this.enablePointerEvents || t(i, 'touchstart', this._onTouchStart, a),
									'undefined' !== typeof r &&
										e in r &&
										(r[e](i, 'gesture', this._onGesture),
										r[e](i, 'drag', this._onDrag),
										r[e](i, 'orientation', this._onOrientationChange),
										r[e](i, 'shake', this._onShake),
										r[e](i, 'longpress', this._onLongPress));
							},
							removeListeners: function () {
								this.addOrRemove(e, 'remove');
								var t = this._getEventPrefix();
								e(n.document, t + 'up', this._onMouseUp),
									e(n.document, 'touchend', this._onTouchEnd, a),
									e(n.document, t + 'move', this._onMouseMove, a),
									e(n.document, 'touchmove', this._onMouseMove, a);
							},
							_bindEvents: function () {
								this.eventsBound ||
									((this._onMouseDown = this._onMouseDown.bind(this)),
									(this._onTouchStart = this._onTouchStart.bind(this)),
									(this._onMouseMove = this._onMouseMove.bind(this)),
									(this._onMouseUp = this._onMouseUp.bind(this)),
									(this._onTouchEnd = this._onTouchEnd.bind(this)),
									(this._onResize = this._onResize.bind(this)),
									(this._onGesture = this._onGesture.bind(this)),
									(this._onDrag = this._onDrag.bind(this)),
									(this._onShake = this._onShake.bind(this)),
									(this._onLongPress = this._onLongPress.bind(this)),
									(this._onOrientationChange = this._onOrientationChange.bind(this)),
									(this._onMouseWheel = this._onMouseWheel.bind(this)),
									(this._onMouseOut = this._onMouseOut.bind(this)),
									(this._onMouseEnter = this._onMouseEnter.bind(this)),
									(this._onContextMenu = this._onContextMenu.bind(this)),
									(this._onDoubleClick = this._onDoubleClick.bind(this)),
									(this._onDragOver = this._onDragOver.bind(this)),
									(this._onDragEnter = this._simpleEventHandler.bind(this, 'dragenter')),
									(this._onDragLeave = this._simpleEventHandler.bind(this, 'dragleave')),
									(this._onDrop = this._onDrop.bind(this)),
									(this.eventsBound = !0));
							},
							_onGesture: function (t, e) {
								this.__onTransformGesture && this.__onTransformGesture(t, e);
							},
							_onDrag: function (t, e) {
								this.__onDrag && this.__onDrag(t, e);
							},
							_onMouseWheel: function (t) {
								this.__onMouseWheel(t);
							},
							_onMouseOut: function (t) {
								var e = this._hoveredTarget;
								this.fire('mouse:out', { target: e, e: t }), (this._hoveredTarget = null), e && e.fire('mouseout', { e: t });
								var i = this;
								this._hoveredTargets.forEach(function (n) {
									i.fire('mouse:out', { target: e, e: t }), n && e.fire('mouseout', { e: t });
								}),
									(this._hoveredTargets = []),
									this._iTextInstances &&
										this._iTextInstances.forEach(function (t) {
											t.isEditing && t.hiddenTextarea.focus();
										});
							},
							_onMouseEnter: function (t) {
								this._currentTransform || this.findTarget(t) || (this.fire('mouse:over', { target: null, e: t }), (this._hoveredTarget = null), (this._hoveredTargets = []));
							},
							_onOrientationChange: function (t, e) {
								this.__onOrientationChange && this.__onOrientationChange(t, e);
							},
							_onShake: function (t, e) {
								this.__onShake && this.__onShake(t, e);
							},
							_onLongPress: function (t, e) {
								this.__onLongPress && this.__onLongPress(t, e);
							},
							_onDragOver: function (t) {
								t.preventDefault();
								var e = this._simpleEventHandler('dragover', t);
								this._fireEnterLeaveEvents(e, t);
							},
							_onDrop: function (t) {
								return this._simpleEventHandler('drop:before', t), this._simpleEventHandler('drop', t);
							},
							_onContextMenu: function (t) {
								return this.stopContextMenu && (t.stopPropagation(), t.preventDefault()), !1;
							},
							_onDoubleClick: function (t) {
								this._cacheTransformEventData(t), this._handleEvent(t, 'dblclick'), this._resetTransformEventData(t);
							},
							getPointerId: function (t) {
								var e = t.changedTouches;
								return e ? e[0] && e[0].identifier : this.enablePointerEvents ? t.pointerId : -1;
							},
							_isMainEvent: function (t) {
								return (
									!0 === t.isPrimary ||
									(!1 !== t.isPrimary && (('touchend' === t.type && 0 === t.touches.length) || !t.changedTouches || t.changedTouches[0].identifier === this.mainTouchId))
								);
							},
							_onTouchStart: function (i) {
								i.preventDefault(), null === this.mainTouchId && (this.mainTouchId = this.getPointerId(i)), this.__onMouseDown(i), this._resetTransformEventData();
								var r = this.upperCanvasEl,
									o = this._getEventPrefix();
								t(n.document, 'touchend', this._onTouchEnd, a), t(n.document, 'touchmove', this._onMouseMove, a), e(r, o + 'down', this._onMouseDown);
							},
							_onMouseDown: function (i) {
								this.__onMouseDown(i), this._resetTransformEventData();
								var r = this.upperCanvasEl,
									o = this._getEventPrefix();
								e(r, o + 'move', this._onMouseMove, a), t(n.document, o + 'up', this._onMouseUp), t(n.document, o + 'move', this._onMouseMove, a);
							},
							_onTouchEnd: function (i) {
								if (!(i.touches.length > 0)) {
									this.__onMouseUp(i), this._resetTransformEventData(), (this.mainTouchId = null);
									var r = this._getEventPrefix();
									e(n.document, 'touchend', this._onTouchEnd, a), e(n.document, 'touchmove', this._onMouseMove, a);
									var o = this;
									this._willAddMouseDown && clearTimeout(this._willAddMouseDown),
										(this._willAddMouseDown = setTimeout(function () {
											t(o.upperCanvasEl, r + 'down', o._onMouseDown), (o._willAddMouseDown = 0);
										}, 400));
								}
							},
							_onMouseUp: function (i) {
								this.__onMouseUp(i), this._resetTransformEventData();
								var r = this.upperCanvasEl,
									o = this._getEventPrefix();
								this._isMainEvent(i) && (e(n.document, o + 'up', this._onMouseUp), e(n.document, o + 'move', this._onMouseMove, a), t(r, o + 'move', this._onMouseMove, a));
							},
							_onMouseMove: function (t) {
								!this.allowTouchScrolling && t.preventDefault && t.preventDefault(), this.__onMouseMove(t);
							},
							_onResize: function () {
								this.calcOffset();
							},
							_shouldRender: function (t) {
								var e = this._activeObject;
								return !!(!!e !== !!t || (e && t && e !== t)) || (e && e.isEditing, !1);
							},
							__onMouseUp: function (t) {
								var e,
									r = this._currentTransform,
									a = this._groupSelector,
									h = !1,
									l = !a || (0 === a.left && 0 === a.top);
								if ((this._cacheTransformEventData(t), (e = this._target), this._handleEvent(t, 'up:before'), c(t, i))) this.fireRightClick && this._handleEvent(t, 'up', i, l);
								else {
									if (c(t, o)) return this.fireMiddleClick && this._handleEvent(t, 'up', o, l), void this._resetTransformEventData();
									if (this.isDrawingMode && this._isCurrentlyDrawing) this._onMouseUpInDrawingMode(t);
									else if (this._isMainEvent(t)) {
										if ((r && (this._finalizeCurrentTransform(t), (h = r.actionPerformed)), !l)) {
											var u = e === this._activeObject;
											this._maybeGroupObjects(t), h || (h = this._shouldRender(e) || (!u && e === this._activeObject));
										}
										var f, d;
										if (e) {
											if (((f = e._findTargetCorner(this.getPointer(t, !0), n.util.isTouchEvent(t))), e.selectable && e !== this._activeObject && 'up' === e.activeOn))
												this.setActiveObject(e, t), (h = !0);
											else {
												var p = e.controls[f],
													g = p && p.getMouseUpHandler(t, e, p);
												g && ((d = this.getPointer(t)), g(t, r, d.x, d.y));
											}
											e.isMoving = !1;
										}
										if (r && (r.target !== e || r.corner !== f)) {
											var v = r.target && r.target.controls[r.corner],
												m = v && v.getMouseUpHandler(t, e, p);
											(d = d || this.getPointer(t)), m && m(t, r, d.x, d.y);
										}
										this._setCursorFromEvent(t, e),
											this._handleEvent(t, 'up', s, l),
											(this._groupSelector = null),
											(this._currentTransform = null),
											e && (e.__corner = 0),
											h ? this.requestRenderAll() : l || this.renderTop();
									}
								}
							},
							_simpleEventHandler: function (t, e) {
								var i = this.findTarget(e),
									n = this.targets,
									r = { e: e, target: i, subTargets: n };
								if ((this.fire(t, r), i && i.fire(t, r), !n)) return i;
								for (var o = 0; o < n.length; o++) n[o].fire(t, r);
								return i;
							},
							_handleEvent: function (t, e, i, n) {
								var r = this._target,
									o = this.targets || [],
									a = {
										e: t,
										target: r,
										subTargets: o,
										button: i || s,
										isClick: n || !1,
										pointer: this._pointer,
										absolutePointer: this._absolutePointer,
										transform: this._currentTransform
									};
								'up' === e && ((a.currentTarget = this.findTarget(t)), (a.currentSubTargets = this.targets)), this.fire('mouse:' + e, a), r && r.fire('mouse' + e, a);
								for (var c = 0; c < o.length; c++) o[c].fire('mouse' + e, a);
							},
							_finalizeCurrentTransform: function (t) {
								var e = this._currentTransform,
									i = e.target,
									n = { e: t, target: i, transform: e, action: e.action };
								i._scaling && (i._scaling = !1), i.setCoords(), (e.actionPerformed || (this.stateful && i.hasStateChanged())) && this._fire('modified', n);
							},
							_onMouseDownInDrawingMode: function (t) {
								(this._isCurrentlyDrawing = !0), this.getActiveObject() && this.discardActiveObject(t).requestRenderAll();
								var e = this.getPointer(t);
								this.freeDrawingBrush.onMouseDown(e, { e: t, pointer: e }), this._handleEvent(t, 'down');
							},
							_onMouseMoveInDrawingMode: function (t) {
								if (this._isCurrentlyDrawing) {
									var e = this.getPointer(t);
									this.freeDrawingBrush.onMouseMove(e, { e: t, pointer: e });
								}
								this.setCursor(this.freeDrawingCursor), this._handleEvent(t, 'move');
							},
							_onMouseUpInDrawingMode: function (t) {
								var e = this.getPointer(t);
								(this._isCurrentlyDrawing = this.freeDrawingBrush.onMouseUp({ e: t, pointer: e })), this._handleEvent(t, 'up');
							},
							__onMouseDown: function (t) {
								this._cacheTransformEventData(t), this._handleEvent(t, 'down:before');
								var e = this._target;
								if (c(t, i)) this.fireRightClick && this._handleEvent(t, 'down', i);
								else if (c(t, o)) this.fireMiddleClick && this._handleEvent(t, 'down', o);
								else if (this.isDrawingMode) this._onMouseDownInDrawingMode(t);
								else if (this._isMainEvent(t) && !this._currentTransform) {
									var r = this._pointer;
									this._previousPointer = r;
									var s = this._shouldRender(e),
										a = this._shouldGroup(t, e);
									if (
										(this._shouldClearSelection(t, e) ? this.discardActiveObject(t) : a && (this._handleGrouping(t, e), (e = this._activeObject)),
										!this.selection ||
											(e && (e.selectable || e.isEditing || e === this._activeObject)) ||
											(this._groupSelector = { ex: this._absolutePointer.x, ey: this._absolutePointer.y, top: 0, left: 0 }),
										e)
									) {
										var h = e === this._activeObject;
										e.selectable && 'down' === e.activeOn && this.setActiveObject(e, t);
										var l = e._findTargetCorner(this.getPointer(t, !0), n.util.isTouchEvent(t));
										if (((e.__corner = l), e === this._activeObject && (l || !a))) {
											this._setupCurrentTransform(t, e, h);
											var u = e.controls[l],
												f = ((r = this.getPointer(t)), u && u.getMouseDownHandler(t, e, u));
											f && f(t, this._currentTransform, r.x, r.y);
										}
									}
									this._handleEvent(t, 'down'), (s || a) && this.requestRenderAll();
								}
							},
							_resetTransformEventData: function () {
								(this._target = null), (this._pointer = null), (this._absolutePointer = null);
							},
							_cacheTransformEventData: function (t) {
								this._resetTransformEventData(),
									(this._pointer = this.getPointer(t, !0)),
									(this._absolutePointer = this.restorePointerVpt(this._pointer)),
									(this._target = this._currentTransform ? this._currentTransform.target : this.findTarget(t) || null);
							},
							_beforeTransform: function (t) {
								var e = this._currentTransform;
								this.stateful && e.target.saveState(), this.fire('before:transform', { e: t, transform: e });
							},
							__onMouseMove: function (t) {
								var e, i;
								if ((this._handleEvent(t, 'move:before'), this._cacheTransformEventData(t), this.isDrawingMode)) this._onMouseMoveInDrawingMode(t);
								else if (this._isMainEvent(t)) {
									var n = this._groupSelector;
									n
										? ((i = this._absolutePointer), (n.left = i.x - n.ex), (n.top = i.y - n.ey), this.renderTop())
										: this._currentTransform
										? this._transformObject(t)
										: ((e = this.findTarget(t) || null), this._setCursorFromEvent(t, e), this._fireOverOutEvents(e, t)),
										this._handleEvent(t, 'move'),
										this._resetTransformEventData();
								}
							},
							_fireOverOutEvents: function (t, e) {
								var i = this._hoveredTarget,
									n = this._hoveredTargets,
									r = this.targets,
									o = Math.max(n.length, r.length);
								this.fireSyntheticInOutEvents(t, e, { oldTarget: i, evtOut: 'mouseout', canvasEvtOut: 'mouse:out', evtIn: 'mouseover', canvasEvtIn: 'mouse:over' });
								for (var s = 0; s < o; s++) this.fireSyntheticInOutEvents(r[s], e, { oldTarget: n[s], evtOut: 'mouseout', evtIn: 'mouseover' });
								(this._hoveredTarget = t), (this._hoveredTargets = this.targets.concat());
							},
							_fireEnterLeaveEvents: function (t, e) {
								var i = this._draggedoverTarget,
									n = this._hoveredTargets,
									r = this.targets,
									o = Math.max(n.length, r.length);
								this.fireSyntheticInOutEvents(t, e, { oldTarget: i, evtOut: 'dragleave', evtIn: 'dragenter' });
								for (var s = 0; s < o; s++) this.fireSyntheticInOutEvents(r[s], e, { oldTarget: n[s], evtOut: 'dragleave', evtIn: 'dragenter' });
								this._draggedoverTarget = t;
							},
							fireSyntheticInOutEvents: function (t, e, i) {
								var n,
									r,
									o,
									s,
									a = i.oldTarget,
									c = a !== t,
									h = i.canvasEvtIn,
									l = i.canvasEvtOut;
								c && ((n = { e: e, target: t, previousTarget: a }), (r = { e: e, target: a, nextTarget: t })),
									(s = t && c),
									(o = a && c),
									o && (l && this.fire(l, r), a.fire(i.evtOut, r)),
									s && (h && this.fire(h, n), t.fire(i.evtIn, n));
							},
							__onMouseWheel: function (t) {
								this._cacheTransformEventData(t), this._handleEvent(t, 'wheel'), this._resetTransformEventData();
							},
							_transformObject: function (t) {
								var e = this.getPointer(t),
									i = this._currentTransform;
								(i.reset = !1), (i.shiftKey = t.shiftKey), (i.altKey = t[this.centeredKey]), this._performTransformAction(t, i, e), i.actionPerformed && this.requestRenderAll();
							},
							_performTransformAction: function (t, e, i) {
								var n = i.x,
									r = i.y,
									o = e.action,
									s = !1,
									a = e.actionHandler;
								a && (s = a(t, e, n, r)),
									'drag' === o && s && ((e.target.isMoving = !0), this.setCursor(e.target.moveCursor || this.moveCursor)),
									(e.actionPerformed = e.actionPerformed || s);
							},
							_fire: n.controlsUtils.fireEvent,
							_setCursorFromEvent: function (t, e) {
								if (!e) return this.setCursor(this.defaultCursor), !1;
								var i = e.hoverCursor || this.hoverCursor,
									n = this._activeObject && 'activeSelection' === this._activeObject.type ? this._activeObject : null,
									r = (!n || !n.contains(e)) && e._findTargetCorner(this.getPointer(t, !0));
								r
									? this.setCursor(this.getCornerCursor(r, e, t))
									: (e.subTargetCheck &&
											this.targets
												.concat()
												.reverse()
												.map(function (t) {
													i = t.hoverCursor || i;
												}),
									  this.setCursor(i));
							},
							getCornerCursor: function (t, e, i) {
								var n = e.controls[t];
								return n.cursorStyleHandler(i, n, e);
							}
						});
					})(),
					(function () {
						var t = Math.min,
							e = Math.max;
						n.util.object.extend(n.Canvas.prototype, {
							_shouldGroup: function (t, e) {
								var i = this._activeObject;
								return i && this._isSelectionKeyPressed(t) && e && e.selectable && this.selection && (i !== e || 'activeSelection' === i.type) && !e.onSelect({ e: t });
							},
							_handleGrouping: function (t, e) {
								var i = this._activeObject;
								i.__corner ||
									((e !== i || ((e = this.findTarget(t, !0)), e && e.selectable)) &&
										(i && 'activeSelection' === i.type ? this._updateActiveSelection(e, t) : this._createActiveSelection(e, t)));
							},
							_updateActiveSelection: function (t, e) {
								var i = this._activeObject,
									n = i._objects.slice(0);
								i.contains(t)
									? (i.removeWithUpdate(t), (this._hoveredTarget = t), (this._hoveredTargets = this.targets.concat()), 1 === i.size() && this._setActiveObject(i.item(0), e))
									: (i.addWithUpdate(t), (this._hoveredTarget = i), (this._hoveredTargets = this.targets.concat())),
									this._fireSelectionEvents(n, e);
							},
							_createActiveSelection: function (t, e) {
								var i = this.getActiveObjects(),
									n = this._createGroup(t);
								(this._hoveredTarget = n), this._setActiveObject(n, e), this._fireSelectionEvents(i, e);
							},
							_createGroup: function (t) {
								var e = this._objects,
									i = e.indexOf(this._activeObject) < e.indexOf(t),
									r = i ? [this._activeObject, t] : [t, this._activeObject];
								return this._activeObject.isEditing && this._activeObject.exitEditing(), new n.ActiveSelection(r, { canvas: this });
							},
							_groupSelectedObjects: function (t) {
								var e,
									i = this._collectObjects(t);
								1 === i.length ? this.setActiveObject(i[0], t) : i.length > 1 && ((e = new n.ActiveSelection(i.reverse(), { canvas: this })), this.setActiveObject(e, t));
							},
							_collectObjects: function (i) {
								for (
									var r,
										o = [],
										s = this._groupSelector.ex,
										a = this._groupSelector.ey,
										c = s + this._groupSelector.left,
										h = a + this._groupSelector.top,
										l = new n.Point(t(s, c), t(a, h)),
										u = new n.Point(e(s, c), e(a, h)),
										f = !this.selectionFullyContained,
										d = s === c && a === h,
										p = this._objects.length;
									p--;

								)
									if (
										((r = this._objects[p]),
										r &&
											r.selectable &&
											r.visible &&
											((f && r.intersectsWithRect(l, u, !0)) ||
												r.isContainedWithinRect(l, u, !0) ||
												(f && r.containsPoint(l, null, !0)) ||
												(f && r.containsPoint(u, null, !0))) &&
											(o.push(r), d))
									)
										break;
								return (
									o.length > 1 &&
										(o = o.filter(function (t) {
											return !t.onSelect({ e: i });
										})),
									o
								);
							},
							_maybeGroupObjects: function (t) {
								this.selection && this._groupSelector && this._groupSelectedObjects(t), this.setCursor(this.defaultCursor), (this._groupSelector = null);
							}
						});
					})(),
					(function () {
						n.util.object.extend(n.StaticCanvas.prototype, {
							toDataURL: function (t) {
								t || (t = {});
								var e = t.format || 'png',
									i = t.quality || 1,
									r = (t.multiplier || 1) * (t.enableRetinaScaling ? this.getRetinaScaling() : 1),
									o = this.toCanvasElement(r, t);
								return n.util.toDataURL(o, e, i);
							},
							toCanvasElement: function (t, e) {
								(t = t || 1), (e = e || {});
								var i = (e.width || this.width) * t,
									r = (e.height || this.height) * t,
									o = this.getZoom(),
									s = this.width,
									a = this.height,
									c = o * t,
									h = this.viewportTransform,
									l = (h[4] - (e.left || 0)) * t,
									u = (h[5] - (e.top || 0)) * t,
									f = this.interactive,
									d = [c, 0, 0, c, l, u],
									p = this.enableRetinaScaling,
									g = n.util.createCanvasElement(),
									v = this.contextTop;
								return (
									(g.width = i),
									(g.height = r),
									(this.contextTop = null),
									(this.enableRetinaScaling = !1),
									(this.interactive = !1),
									(this.viewportTransform = d),
									(this.width = i),
									(this.height = r),
									this.calcViewportBoundaries(),
									this.renderCanvas(g.getContext('2d'), this._objects),
									(this.viewportTransform = h),
									(this.width = s),
									(this.height = a),
									this.calcViewportBoundaries(),
									(this.interactive = f),
									(this.enableRetinaScaling = p),
									(this.contextTop = v),
									g
								);
							}
						});
					})(),
					n.util.object.extend(n.StaticCanvas.prototype, {
						loadFromJSON: function (t, e, i) {
							if (t) {
								var r = 'string' === typeof t ? JSON.parse(t) : n.util.object.clone(t),
									o = this,
									s = r.clipPath,
									a = this.renderOnAddRemove;
								return (
									(this.renderOnAddRemove = !1),
									delete r.clipPath,
									this._enlivenObjects(
										r.objects,
										function (t) {
											o.clear(),
												o._setBgOverlay(r, function () {
													s
														? o._enlivenObjects([s], function (i) {
																(o.clipPath = i[0]), o.__setupCanvas.call(o, r, t, a, e);
														  })
														: o.__setupCanvas.call(o, r, t, a, e);
												});
										},
										i
									),
									this
								);
							}
						},
						__setupCanvas: function (t, e, i, n) {
							var r = this;
							e.forEach(function (t, e) {
								r.insertAt(t, e);
							}),
								(this.renderOnAddRemove = i),
								delete t.objects,
								delete t.backgroundImage,
								delete t.overlayImage,
								delete t.background,
								delete t.overlay,
								this._setOptions(t),
								this.renderAll(),
								n && n();
						},
						_setBgOverlay: function (t, e) {
							var i = { backgroundColor: !1, overlayColor: !1, backgroundImage: !1, overlayImage: !1 };
							if (t.backgroundImage || t.overlayImage || t.background || t.overlay) {
								var n = function () {
									i.backgroundImage && i.overlayImage && i.backgroundColor && i.overlayColor && e && e();
								};
								this.__setBgOverlay('backgroundImage', t.backgroundImage, i, n),
									this.__setBgOverlay('overlayImage', t.overlayImage, i, n),
									this.__setBgOverlay('backgroundColor', t.background, i, n),
									this.__setBgOverlay('overlayColor', t.overlay, i, n);
							} else e && e();
						},
						__setBgOverlay: function (t, e, i, r) {
							var o = this;
							if (!e) return (i[t] = !0), void (r && r());
							'backgroundImage' === t || 'overlayImage' === t
								? n.util.enlivenObjects([e], function (e) {
										(o[t] = e[0]), (i[t] = !0), r && r();
								  })
								: this['set' + n.util.string.capitalize(t, !0)](e, function () {
										(i[t] = !0), r && r();
								  });
						},
						_enlivenObjects: function (t, e, i) {
							t && 0 !== t.length
								? n.util.enlivenObjects(
										t,
										function (t) {
											e && e(t);
										},
										null,
										i
								  )
								: e && e([]);
						},
						_toDataURL: function (t, e) {
							this.clone(function (i) {
								e(i.toDataURL(t));
							});
						},
						_toDataURLWithMultiplier: function (t, e, i) {
							this.clone(function (n) {
								i(n.toDataURLWithMultiplier(t, e));
							});
						},
						clone: function (t, e) {
							var i = JSON.stringify(this.toJSON(e));
							this.cloneWithoutData(function (e) {
								e.loadFromJSON(i, function () {
									t && t(e);
								});
							});
						},
						cloneWithoutData: function (t) {
							var e = n.util.createCanvasElement();
							(e.width = this.width), (e.height = this.height);
							var i = new n.Canvas(e);
							this.backgroundImage
								? (i.setBackgroundImage(this.backgroundImage.src, function () {
										i.renderAll(), t && t(i);
								  }),
								  (i.backgroundImageOpacity = this.backgroundImageOpacity),
								  (i.backgroundImageStretch = this.backgroundImageStretch))
								: t && t(i);
						}
					}),
					(function () {
						var t = n.util.degreesToRadians,
							e = n.util.radiansToDegrees;
						n.util.object.extend(n.Canvas.prototype, {
							__onTransformGesture: function (t, e) {
								if (!this.isDrawingMode && t.touches && 2 === t.touches.length && 'gesture' === e.gesture) {
									var i = this.findTarget(t);
									'undefined' !== typeof i && ((this.__gesturesParams = { e: t, self: e, target: i }), this.__gesturesRenderer()),
										this.fire('touch:gesture', { target: i, e: t, self: e });
								}
							},
							__gesturesParams: null,
							__gesturesRenderer: function () {
								if (null !== this.__gesturesParams && null !== this._currentTransform) {
									var t = this.__gesturesParams.self,
										e = this._currentTransform,
										i = this.__gesturesParams.e;
									(e.action = 'scale'),
										(e.originX = e.originY = 'center'),
										this._scaleObjectBy(t.scale, i),
										0 !== t.rotation && ((e.action = 'rotate'), this._rotateObjectByAngle(t.rotation, i)),
										this.requestRenderAll(),
										(e.action = 'drag');
								}
							},
							__onDrag: function (t, e) {
								this.fire('touch:drag', { e: t, self: e });
							},
							__onOrientationChange: function (t, e) {
								this.fire('touch:orientation', { e: t, self: e });
							},
							__onShake: function (t, e) {
								this.fire('touch:shake', { e: t, self: e });
							},
							__onLongPress: function (t, e) {
								this.fire('touch:longpress', { e: t, self: e });
							},
							_scaleObjectBy: function (t, e) {
								var i = this._currentTransform,
									r = i.target;
								return (i.gestureScale = t), (r._scaling = !0), n.controlsUtils.scalingEqually(e, i, 0, 0);
							},
							_rotateObjectByAngle: function (i, n) {
								var r = this._currentTransform;
								r.target.get('lockRotation') || (r.target.rotate(e(t(i) + r.theta)), this._fire('rotating', { target: r.target, e: n, transform: r }));
							}
						});
					})(),
					(function (t) {
						'use strict';
						var e = t.fabric || (t.fabric = {}),
							i = e.util.object.extend,
							n = e.util.object.clone,
							r = e.util.toFixed,
							o = e.util.string.capitalize,
							s = e.util.degreesToRadians,
							a = !e.isLikelyNode,
							c = 2;
						e.Object ||
							((e.Object = e.util.createClass(e.CommonMethods, {
								type: 'object',
								originX: 'left',
								originY: 'top',
								top: 0,
								left: 0,
								width: 0,
								height: 0,
								scaleX: 1,
								scaleY: 1,
								flipX: !1,
								flipY: !1,
								opacity: 1,
								angle: 0,
								skewX: 0,
								skewY: 0,
								cornerSize: 13,
								touchCornerSize: 24,
								transparentCorners: !0,
								hoverCursor: null,
								moveCursor: null,
								padding: 0,
								borderColor: 'rgb(178,204,255)',
								borderDashArray: null,
								cornerColor: 'rgb(178,204,255)',
								cornerStrokeColor: null,
								cornerStyle: 'rect',
								cornerDashArray: null,
								centeredScaling: !1,
								centeredRotation: !0,
								fill: 'rgb(0,0,0)',
								fillRule: 'nonzero',
								globalCompositeOperation: 'source-over',
								backgroundColor: '',
								selectionBackgroundColor: '',
								stroke: null,
								strokeWidth: 1,
								strokeDashArray: null,
								strokeDashOffset: 0,
								strokeLineCap: 'butt',
								strokeLineJoin: 'miter',
								strokeMiterLimit: 4,
								shadow: null,
								borderOpacityWhenMoving: 0.4,
								borderScaleFactor: 1,
								minScaleLimit: 0,
								selectable: !0,
								evented: !0,
								visible: !0,
								hasControls: !1,
								hasBorders: !0,
								perPixelTargetFind: !1,
								includeDefaultValues: !0,
								lockMovementX: !1,
								lockMovementY: !1,
								lockRotation: !0,
								lockScalingX: !0,
								lockScalingY: !0,
								lockSkewingX: !0,
								lockSkewingY: !0,
								lockScalingFlip: !0,
								excludeFromExport: !1,
								objectCaching: a,
								statefullCache: !1,
								noScaleCache: !0,
								strokeUniform: !1,
								dirty: !0,
								__corner: 0,
								paintFirst: 'fill',
								activeOn: 'down',
								stateProperties:
									'top left width height scaleX scaleY flipX flipY originX originY transformMatrix stroke strokeWidth strokeDashArray strokeLineCap strokeDashOffset strokeLineJoin strokeMiterLimit angle opacity fill globalCompositeOperation shadow visible backgroundColor skewX skewY fillRule paintFirst clipPath strokeUniform'.split(
										' '
									),
								cacheProperties:
									'fill stroke strokeWidth strokeDashArray width height paintFirst strokeUniform strokeLineCap strokeDashOffset strokeLineJoin strokeMiterLimit backgroundColor clipPath'.split(
										' '
									),
								colorProperties: 'fill stroke backgroundColor'.split(' '),
								clipPath: void 0,
								inverted: !1,
								absolutePositioned: !1,
								initialize: function (t) {
									t && this.setOptions(t);
								},
								_createCacheCanvas: function () {
									(this._cacheProperties = {}),
										(this._cacheCanvas = e.util.createCanvasElement()),
										(this._cacheContext = this._cacheCanvas.getContext('2d')),
										this._updateCacheCanvas(),
										(this.dirty = !0);
								},
								_limitCacheSize: function (t) {
									var i = e.perfLimitSizeTotal,
										n = t.width,
										r = t.height,
										o = e.maxCacheSideLimit,
										s = e.minCacheSideLimit;
									if (n <= o && r <= o && n * r <= i) return n < s && (t.width = s), r < s && (t.height = s), t;
									var a = n / r,
										c = e.util.limitDimsByArea(a, i),
										h = e.util.capValue,
										l = h(s, c.x, o),
										u = h(s, c.y, o);
									return n > l && ((t.zoomX /= n / l), (t.width = l), (t.capped = !0)), r > u && ((t.zoomY /= r / u), (t.height = u), (t.capped = !0)), t;
								},
								_getCacheCanvasDimensions: function () {
									var t = this.getTotalObjectScaling(),
										e = this._getTransformedDimensions(0, 0),
										i = (e.x * t.scaleX) / this.scaleX,
										n = (e.y * t.scaleY) / this.scaleY;
									return { width: i + c, height: n + c, zoomX: t.scaleX, zoomY: t.scaleY, x: i, y: n };
								},
								_updateCacheCanvas: function () {
									var t = this.canvas;
									if (this.noScaleCache && t && t._currentTransform) {
										var i = t._currentTransform.target,
											n = t._currentTransform.action;
										if (this === i && n.slice && 'scale' === n.slice(0, 5)) return !1;
									}
									var r,
										o,
										s = this._cacheCanvas,
										a = this._limitCacheSize(this._getCacheCanvasDimensions()),
										c = e.minCacheSideLimit,
										h = a.width,
										l = a.height,
										u = a.zoomX,
										f = a.zoomY,
										d = h !== this.cacheWidth || l !== this.cacheHeight,
										p = this.zoomX !== u || this.zoomY !== f,
										g = d || p,
										v = 0,
										m = 0,
										y = !1;
									if (d) {
										var b = this._cacheCanvas.width,
											x = this._cacheCanvas.height,
											_ = h > b || l > x,
											w = (h < 0.9 * b || l < 0.9 * x) && b > c && x > c;
										(y = _ || w), _ && !a.capped && (h > c || l > c) && ((v = 0.1 * h), (m = 0.1 * l));
									}
									return (
										this instanceof e.Text && this.path && ((g = !0), (y = !0), (v += this.getHeightOfLine(0) * this.zoomX), (m += this.getHeightOfLine(0) * this.zoomY)),
										!!g &&
											(y
												? ((s.width = Math.ceil(h + v)), (s.height = Math.ceil(l + m)))
												: (this._cacheContext.setTransform(1, 0, 0, 1, 0, 0), this._cacheContext.clearRect(0, 0, s.width, s.height)),
											(r = a.x / 2),
											(o = a.y / 2),
											(this.cacheTranslationX = Math.round(s.width / 2 - r) + r),
											(this.cacheTranslationY = Math.round(s.height / 2 - o) + o),
											(this.cacheWidth = h),
											(this.cacheHeight = l),
											this._cacheContext.translate(this.cacheTranslationX, this.cacheTranslationY),
											this._cacheContext.scale(u, f),
											(this.zoomX = u),
											(this.zoomY = f),
											!0)
									);
								},
								setOptions: function (t) {
									this._setOptions(t),
										this._initGradient(t.fill, 'fill'),
										this._initGradient(t.stroke, 'stroke'),
										this._initPattern(t.fill, 'fill'),
										this._initPattern(t.stroke, 'stroke');
								},
								transform: function (t) {
									var e = (this.group && !this.group._transformDone) || (this.group && this.canvas && t === this.canvas.contextTop),
										i = this.calcTransformMatrix(!e);
									t.transform(i[0], i[1], i[2], i[3], i[4], i[5]);
								},
								toObject: function (t) {
									var i = e.Object.NUM_FRACTION_DIGITS,
										n = {
											type: this.type,
											version: e.version,
											originX: this.originX,
											originY: this.originY,
											left: r(this.left, i),
											top: r(this.top, i),
											width: r(this.width, i),
											height: r(this.height, i),
											fill: this.fill && this.fill.toObject ? this.fill.toObject() : this.fill,
											stroke: this.stroke && this.stroke.toObject ? this.stroke.toObject() : this.stroke,
											strokeWidth: r(this.strokeWidth, i),
											strokeDashArray: this.strokeDashArray ? this.strokeDashArray.concat() : this.strokeDashArray,
											strokeLineCap: this.strokeLineCap,
											strokeDashOffset: this.strokeDashOffset,
											strokeLineJoin: this.strokeLineJoin,
											strokeUniform: this.strokeUniform,
											strokeMiterLimit: r(this.strokeMiterLimit, i),
											scaleX: r(this.scaleX, i),
											scaleY: r(this.scaleY, i),
											angle: r(this.angle, i),
											flipX: this.flipX,
											flipY: this.flipY,
											opacity: r(this.opacity, i),
											shadow: this.shadow && this.shadow.toObject ? this.shadow.toObject() : this.shadow,
											visible: this.visible,
											backgroundColor: this.backgroundColor,
											fillRule: this.fillRule,
											paintFirst: this.paintFirst,
											globalCompositeOperation: this.globalCompositeOperation,
											skewX: r(this.skewX, i),
											skewY: r(this.skewY, i)
										};
									return (
										this.clipPath &&
											!this.clipPath.excludeFromExport &&
											((n.clipPath = this.clipPath.toObject(t)),
											(n.clipPath.inverted = this.clipPath.inverted),
											(n.clipPath.absolutePositioned = this.clipPath.absolutePositioned)),
										e.util.populateWithProperties(this, n, t),
										this.includeDefaultValues || (n = this._removeDefaultValues(n)),
										n
									);
								},
								toDatalessObject: function (t) {
									return this.toObject(t);
								},
								_removeDefaultValues: function (t) {
									var i = e.util.getKlass(t.type).prototype,
										n = i.stateProperties;
									return (
										n.forEach(function (e) {
											'left' !== e &&
												'top' !== e &&
												(t[e] === i[e] && delete t[e], Array.isArray(t[e]) && Array.isArray(i[e]) && 0 === t[e].length && 0 === i[e].length && delete t[e]);
										}),
										t
									);
								},
								toString: function () {
									return '#<fabric.' + o(this.type) + '>';
								},
								getObjectScaling: function () {
									if (!this.group) return { scaleX: this.scaleX, scaleY: this.scaleY };
									var t = e.util.qrDecompose(this.calcTransformMatrix());
									return { scaleX: Math.abs(t.scaleX), scaleY: Math.abs(t.scaleY) };
								},
								getTotalObjectScaling: function () {
									var t = this.getObjectScaling(),
										e = t.scaleX,
										i = t.scaleY;
									if (this.canvas) {
										var n = this.canvas.getZoom(),
											r = this.canvas.getRetinaScaling();
										(e *= n * r), (i *= n * r);
									}
									return { scaleX: e, scaleY: i };
								},
								getObjectOpacity: function () {
									var t = this.opacity;
									return this.group && (t *= this.group.getObjectOpacity()), t;
								},
								_set: function (t, i) {
									var n = 'scaleX' === t || 'scaleY' === t,
										r = this[t] !== i,
										o = !1;
									return (
										n && (i = this._constrainScale(i)),
										'scaleX' === t && i < 0
											? ((this.flipX = !this.flipX), (i *= -1))
											: 'scaleY' === t && i < 0
											? ((this.flipY = !this.flipY), (i *= -1))
											: 'shadow' !== t || !i || i instanceof e.Shadow
											? 'dirty' === t && this.group && this.group.set('dirty', i)
											: (i = new e.Shadow(i)),
										(this[t] = i),
										r &&
											((o = this.group && this.group.isOnACache()),
											this.cacheProperties.indexOf(t) > -1
												? ((this.dirty = !0), o && this.group.set('dirty', !0))
												: o && this.stateProperties.indexOf(t) > -1 && this.group.set('dirty', !0)),
										this
									);
								},
								setOnGroup: function () {},
								getViewportTransform: function () {
									return this.canvas && this.canvas.viewportTransform ? this.canvas.viewportTransform : e.iMatrix.concat();
								},
								isNotVisible: function () {
									return 0 === this.opacity || (!this.width && !this.height && 0 === this.strokeWidth) || !this.visible;
								},
								render: function (t) {
									this.isNotVisible() ||
										(this.canvas && this.canvas.skipOffscreen && !this.group && !this.isOnScreen()) ||
										(t.save(),
										this._setupCompositeOperation(t),
										this.drawSelectionBackground(t),
										this.transform(t),
										this._setOpacity(t),
										this._setShadow(t, this),
										this.shouldCache()
											? (this.renderCache(), this.drawCacheOnCanvas(t))
											: (this._removeCacheCanvas(),
											  (this.dirty = !1),
											  this.drawObject(t),
											  this.objectCaching && this.statefullCache && this.saveState({ propertySet: 'cacheProperties' })),
										t.restore());
								},
								renderCache: function (t) {
									(t = t || {}),
										(this._cacheCanvas && this._cacheContext) || this._createCacheCanvas(),
										this.isCacheDirty() &&
											(this.statefullCache && this.saveState({ propertySet: 'cacheProperties' }), this.drawObject(this._cacheContext, t.forClipping), (this.dirty = !1));
								},
								_removeCacheCanvas: function () {
									(this._cacheCanvas = null), (this._cacheContext = null), (this.cacheWidth = 0), (this.cacheHeight = 0);
								},
								hasStroke: function () {
									return this.stroke && 'transparent' !== this.stroke && 0 !== this.strokeWidth;
								},
								hasFill: function () {
									return this.fill && 'transparent' !== this.fill;
								},
								needsItsOwnCache: function () {
									return !('stroke' !== this.paintFirst || !this.hasFill() || !this.hasStroke() || 'object' !== typeof this.shadow) || !!this.clipPath;
								},
								shouldCache: function () {
									return (this.ownCaching = this.needsItsOwnCache() || (this.objectCaching && (!this.group || !this.group.isOnACache()))), this.ownCaching;
								},
								willDrawShadow: function () {
									return !!this.shadow && (0 !== this.shadow.offsetX || 0 !== this.shadow.offsetY);
								},
								drawClipPathOnCache: function (t, i) {
									if ((t.save(), i.inverted ? (t.globalCompositeOperation = 'destination-out') : (t.globalCompositeOperation = 'destination-in'), i.absolutePositioned)) {
										var n = e.util.invertTransform(this.calcTransformMatrix());
										t.transform(n[0], n[1], n[2], n[3], n[4], n[5]);
									}
									i.transform(t), t.scale(1 / i.zoomX, 1 / i.zoomY), t.drawImage(i._cacheCanvas, -i.cacheTranslationX, -i.cacheTranslationY), t.restore();
								},
								drawObject: function (t, e) {
									var i = this.fill,
										n = this.stroke;
									e ? ((this.fill = 'black'), (this.stroke = ''), this._setClippingProperties(t)) : this._renderBackground(t),
										this._render(t),
										this._drawClipPath(t, this.clipPath),
										(this.fill = i),
										(this.stroke = n);
								},
								_drawClipPath: function (t, e) {
									e && ((e.canvas = this.canvas), e.shouldCache(), (e._transformDone = !0), e.renderCache({ forClipping: !0 }), this.drawClipPathOnCache(t, e));
								},
								drawCacheOnCanvas: function (t) {
									t.scale(1 / this.zoomX, 1 / this.zoomY), t.drawImage(this._cacheCanvas, -this.cacheTranslationX, -this.cacheTranslationY);
								},
								isCacheDirty: function (t) {
									if (this.isNotVisible()) return !1;
									if (this._cacheCanvas && this._cacheContext && !t && this._updateCacheCanvas()) return !0;
									if (this.dirty || (this.clipPath && this.clipPath.absolutePositioned) || (this.statefullCache && this.hasStateChanged('cacheProperties'))) {
										if (this._cacheCanvas && this._cacheContext && !t) {
											var e = this.cacheWidth / this.zoomX,
												i = this.cacheHeight / this.zoomY;
											this._cacheContext.clearRect(-e / 2, -i / 2, e, i);
										}
										return !0;
									}
									return !1;
								},
								_renderBackground: function (t) {
									if (this.backgroundColor) {
										var e = this._getNonTransformedDimensions();
										(t.fillStyle = this.backgroundColor), t.fillRect(-e.x / 2, -e.y / 2, e.x, e.y), this._removeShadow(t);
									}
								},
								_setOpacity: function (t) {
									this.group && !this.group._transformDone ? (t.globalAlpha = this.getObjectOpacity()) : (t.globalAlpha *= this.opacity);
								},
								_setStrokeStyles: function (t, e) {
									var i = e.stroke;
									i &&
										((t.lineWidth = e.strokeWidth),
										(t.lineCap = e.strokeLineCap),
										(t.lineDashOffset = e.strokeDashOffset),
										(t.lineJoin = e.strokeLineJoin),
										(t.miterLimit = e.strokeMiterLimit),
										i.toLive
											? 'percentage' === i.gradientUnits || i.gradientTransform || i.patternTransform
												? this._applyPatternForTransformedGradient(t, i)
												: ((t.strokeStyle = i.toLive(t, this)), this._applyPatternGradientTransform(t, i))
											: (t.strokeStyle = e.stroke));
								},
								_setFillStyles: function (t, e) {
									var i = e.fill;
									i && (i.toLive ? ((t.fillStyle = i.toLive(t, this)), this._applyPatternGradientTransform(t, e.fill)) : (t.fillStyle = i));
								},
								_setClippingProperties: function (t) {
									(t.globalAlpha = 1), (t.strokeStyle = 'transparent'), (t.fillStyle = '#000000');
								},
								_setLineDash: function (t, e) {
									e && 0 !== e.length && (1 & e.length && e.push.apply(e, e), t.setLineDash(e));
								},
								_renderControls: function (t, i) {
									var n,
										r,
										o,
										a = this.getViewportTransform(),
										c = this.calcTransformMatrix();
									(i = i || {}),
										(r = 'undefined' !== typeof i.hasBorders ? i.hasBorders : this.hasBorders),
										(o = 'undefined' !== typeof i.hasControls ? i.hasControls : this.hasControls),
										(c = e.util.multiplyTransformMatrices(a, c)),
										(n = e.util.qrDecompose(c)),
										t.save(),
										t.translate(n.translateX, n.translateY),
										(t.lineWidth = 1 * this.borderScaleFactor),
										this.group || (t.globalAlpha = this.isMoving ? this.borderOpacityWhenMoving : 1),
										this.flipX && (n.angle -= 180),
										t.rotate(s(this.group ? n.angle : this.angle)),
										i.forActiveSelection || this.group ? r && this.drawBordersInGroup(t, n, i) : r && this.drawBorders(t, i),
										o && this.drawControls(t, i),
										t.restore();
								},
								_setShadow: function (t) {
									if (this.shadow) {
										var i,
											n = this.shadow,
											r = this.canvas,
											o = (r && r.viewportTransform[0]) || 1,
											s = (r && r.viewportTransform[3]) || 1;
										(i = n.nonScaling ? { scaleX: 1, scaleY: 1 } : this.getObjectScaling()),
											r && r._isRetinaScaling() && ((o *= e.devicePixelRatio), (s *= e.devicePixelRatio)),
											(t.shadowColor = n.color),
											(t.shadowBlur = (n.blur * e.browserShadowBlurConstant * (o + s) * (i.scaleX + i.scaleY)) / 4),
											(t.shadowOffsetX = n.offsetX * o * i.scaleX),
											(t.shadowOffsetY = n.offsetY * s * i.scaleY);
									}
								},
								_removeShadow: function (t) {
									this.shadow && ((t.shadowColor = ''), (t.shadowBlur = t.shadowOffsetX = t.shadowOffsetY = 0));
								},
								_applyPatternGradientTransform: function (t, e) {
									if (!e || !e.toLive) return { offsetX: 0, offsetY: 0 };
									var i = e.gradientTransform || e.patternTransform,
										n = -this.width / 2 + e.offsetX || 0,
										r = -this.height / 2 + e.offsetY || 0;
									return (
										'percentage' === e.gradientUnits ? t.transform(this.width, 0, 0, this.height, n, r) : t.transform(1, 0, 0, 1, n, r),
										i && t.transform(i[0], i[1], i[2], i[3], i[4], i[5]),
										{ offsetX: n, offsetY: r }
									);
								},
								_renderPaintInOrder: function (t) {
									'stroke' === this.paintFirst ? (this._renderStroke(t), this._renderFill(t)) : (this._renderFill(t), this._renderStroke(t));
								},
								_render: function () {},
								_renderFill: function (t) {
									this.fill && (t.save(), this._setFillStyles(t, this), 'evenodd' === this.fillRule ? t.fill('evenodd') : t.fill(), t.restore());
								},
								_renderStroke: function (t) {
									if (this.stroke && 0 !== this.strokeWidth) {
										if ((this.shadow && !this.shadow.affectStroke && this._removeShadow(t), t.save(), this.strokeUniform && this.group)) {
											var e = this.getObjectScaling();
											t.scale(1 / e.scaleX, 1 / e.scaleY);
										} else this.strokeUniform && t.scale(1 / this.scaleX, 1 / this.scaleY);
										this._setLineDash(t, this.strokeDashArray), this._setStrokeStyles(t, this), t.stroke(), t.restore();
									}
								},
								_applyPatternForTransformedGradient: function (t, i) {
									var n,
										r = this._limitCacheSize(this._getCacheCanvasDimensions()),
										o = e.util.createCanvasElement(),
										s = this.canvas.getRetinaScaling(),
										a = r.x / this.scaleX / s,
										c = r.y / this.scaleY / s;
									(o.width = a),
										(o.height = c),
										(n = o.getContext('2d')),
										n.beginPath(),
										n.moveTo(0, 0),
										n.lineTo(a, 0),
										n.lineTo(a, c),
										n.lineTo(0, c),
										n.closePath(),
										n.translate(a / 2, c / 2),
										n.scale(r.zoomX / this.scaleX / s, r.zoomY / this.scaleY / s),
										this._applyPatternGradientTransform(n, i),
										(n.fillStyle = i.toLive(t)),
										n.fill(),
										t.translate(-this.width / 2 - this.strokeWidth / 2, -this.height / 2 - this.strokeWidth / 2),
										t.scale((s * this.scaleX) / r.zoomX, (s * this.scaleY) / r.zoomY),
										(t.strokeStyle = n.createPattern(o, 'no-repeat'));
								},
								_findCenterFromElement: function () {
									return { x: this.left + this.width / 2, y: this.top + this.height / 2 };
								},
								_assignTransformMatrixProps: function () {
									if (this.transformMatrix) {
										var t = e.util.qrDecompose(this.transformMatrix);
										(this.flipX = !1),
											(this.flipY = !1),
											this.set('scaleX', t.scaleX),
											this.set('scaleY', t.scaleY),
											(this.angle = t.angle),
											(this.skewX = t.skewX),
											(this.skewY = 0);
									}
								},
								_removeTransformMatrix: function (t) {
									var i = this._findCenterFromElement();
									this.transformMatrix && (this._assignTransformMatrixProps(), (i = e.util.transformPoint(i, this.transformMatrix))),
										(this.transformMatrix = null),
										t &&
											((this.scaleX *= t.scaleX),
											(this.scaleY *= t.scaleY),
											(this.cropX = t.cropX),
											(this.cropY = t.cropY),
											(i.x += t.offsetLeft),
											(i.y += t.offsetTop),
											(this.width = t.width),
											(this.height = t.height)),
										this.setPositionByOrigin(i, 'center', 'center');
								},
								clone: function (t, i) {
									var n = this.toObject(i);
									this.constructor.fromObject ? this.constructor.fromObject(n, t) : e.Object._fromObject('Object', n, t);
								},
								cloneAsImage: function (t, i) {
									var n = this.toCanvasElement(i);
									return t && t(new e.Image(n)), this;
								},
								toCanvasElement: function (t) {
									t || (t = {});
									var i = e.util,
										n = i.saveObjectTransform(this),
										r = this.group,
										o = this.shadow,
										s = Math.abs,
										a = (t.multiplier || 1) * (t.enableRetinaScaling ? e.devicePixelRatio : 1);
									delete this.group, t.withoutTransform && i.resetObjectTransform(this), t.withoutShadow && (this.shadow = null);
									var c,
										h,
										l,
										u,
										f = e.util.createCanvasElement(),
										d = this.getBoundingRect(!0, !0),
										p = this.shadow,
										g = { x: 0, y: 0 };
									p &&
										((h = p.blur),
										(c = p.nonScaling ? { scaleX: 1, scaleY: 1 } : this.getObjectScaling()),
										(g.x = 2 * Math.round(s(p.offsetX) + h) * s(c.scaleX)),
										(g.y = 2 * Math.round(s(p.offsetY) + h) * s(c.scaleY))),
										(l = d.width + g.x),
										(u = d.height + g.y),
										(f.width = Math.ceil(l)),
										(f.height = Math.ceil(u));
									var v = new e.StaticCanvas(f, { enableRetinaScaling: !1, renderOnAddRemove: !1, skipOffscreen: !1 });
									'jpeg' === t.format && (v.backgroundColor = '#fff'), this.setPositionByOrigin(new e.Point(v.width / 2, v.height / 2), 'center', 'center');
									var m = this.canvas;
									v.add(this);
									var y = v.toCanvasElement(a || 1, t);
									return (this.shadow = o), this.set('canvas', m), r && (this.group = r), this.set(n).setCoords(), (v._objects = []), v.dispose(), (v = null), y;
								},
								toDataURL: function (t) {
									return t || (t = {}), e.util.toDataURL(this.toCanvasElement(t), t.format || 'png', t.quality || 1);
								},
								isType: function (t) {
									return arguments.length > 1 ? Array.from(arguments).includes(this.type) : this.type === t;
								},
								complexity: function () {
									return 1;
								},
								toJSON: function (t) {
									return this.toObject(t);
								},
								rotate: function (t) {
									var e = ('center' !== this.originX || 'center' !== this.originY) && this.centeredRotation;
									return e && this._setOriginToCenter(), this.set('angle', t), e && this._resetOrigin(), this;
								},
								centerH: function () {
									return this.canvas && this.canvas.centerObjectH(this), this;
								},
								viewportCenterH: function () {
									return this.canvas && this.canvas.viewportCenterObjectH(this), this;
								},
								centerV: function () {
									return this.canvas && this.canvas.centerObjectV(this), this;
								},
								viewportCenterV: function () {
									return this.canvas && this.canvas.viewportCenterObjectV(this), this;
								},
								center: function () {
									return this.canvas && this.canvas.centerObject(this), this;
								},
								viewportCenter: function () {
									return this.canvas && this.canvas.viewportCenterObject(this), this;
								},
								getLocalPointer: function (t, i) {
									i = i || this.canvas.getPointer(t);
									var n = new e.Point(i.x, i.y),
										r = this._getLeftTopCoords();
									return this.angle && (n = e.util.rotatePoint(n, r, s(-this.angle))), { x: n.x - r.x, y: n.y - r.y };
								},
								_setupCompositeOperation: function (t) {
									this.globalCompositeOperation && (t.globalCompositeOperation = this.globalCompositeOperation);
								},
								dispose: function () {
									e.runningAnimations && e.runningAnimations.cancelByTarget(this);
								}
							})),
							e.util.createAccessors && e.util.createAccessors(e.Object),
							i(e.Object.prototype, e.Observable),
							(e.Object.NUM_FRACTION_DIGITS = 2),
							(e.Object.ENLIVEN_PROPS = ['clipPath']),
							(e.Object._fromObject = function (t, i, r, o) {
								var s = e[t];
								(i = n(i, !0)),
									e.util.enlivenPatterns([i.fill, i.stroke], function (t) {
										'undefined' !== typeof t[0] && (i.fill = t[0]),
											'undefined' !== typeof t[1] && (i.stroke = t[1]),
											e.util.enlivenObjectEnlivables(i, i, function () {
												var t = o ? new s(i[o], i) : new s(i);
												r && r(t);
											});
									});
							}),
							(e.Object.__uid = 0));
					})(e),
					(function () {
						var t = n.util.degreesToRadians,
							e = { left: -0.5, center: 0, right: 0.5 },
							i = { top: -0.5, center: 0, bottom: 0.5 };
						n.util.object.extend(n.Object.prototype, {
							translateToGivenOrigin: function (t, r, o, s, a) {
								var c,
									h,
									l,
									u = t.x,
									f = t.y;
								return (
									'string' === typeof r ? (r = e[r]) : (r -= 0.5),
									'string' === typeof s ? (s = e[s]) : (s -= 0.5),
									(c = s - r),
									'string' === typeof o ? (o = i[o]) : (o -= 0.5),
									'string' === typeof a ? (a = i[a]) : (a -= 0.5),
									(h = a - o),
									(c || h) && ((l = this._getTransformedDimensions()), (u = t.x + c * l.x), (f = t.y + h * l.y)),
									new n.Point(u, f)
								);
							},
							translateToCenterPoint: function (e, i, r) {
								var o = this.translateToGivenOrigin(e, i, r, 'center', 'center');
								return this.angle ? n.util.rotatePoint(o, e, t(this.angle)) : o;
							},
							translateToOriginPoint: function (e, i, r) {
								var o = this.translateToGivenOrigin(e, 'center', 'center', i, r);
								return this.angle ? n.util.rotatePoint(o, e, t(this.angle)) : o;
							},
							getCenterPoint: function () {
								var t = new n.Point(this.left, this.top);
								return this.translateToCenterPoint(t, this.originX, this.originY);
							},
							getPointByOrigin: function (t, e) {
								var i = this.getCenterPoint();
								return this.translateToOriginPoint(i, t, e);
							},
							toLocalPoint: function (e, i, r) {
								var o,
									s,
									a = this.getCenterPoint();
								return (
									(o = 'undefined' !== typeof i && 'undefined' !== typeof r ? this.translateToGivenOrigin(a, 'center', 'center', i, r) : new n.Point(this.left, this.top)),
									(s = new n.Point(e.x, e.y)),
									this.angle && (s = n.util.rotatePoint(s, a, -t(this.angle))),
									s.subtractEquals(o)
								);
							},
							setPositionByOrigin: function (t, e, i) {
								var n = this.translateToCenterPoint(t, e, i),
									r = this.translateToOriginPoint(n, this.originX, this.originY);
								this.set('left', r.x), this.set('top', r.y);
							},
							adjustPosition: function (i) {
								var r,
									o,
									s = t(this.angle),
									a = this.getScaledWidth(),
									c = n.util.cos(s) * a,
									h = n.util.sin(s) * a;
								(r = 'string' === typeof this.originX ? e[this.originX] : this.originX - 0.5),
									(o = 'string' === typeof i ? e[i] : i - 0.5),
									(this.left += c * (o - r)),
									(this.top += h * (o - r)),
									this.setCoords(),
									(this.originX = i);
							},
							_setOriginToCenter: function () {
								(this._originalOriginX = this.originX), (this._originalOriginY = this.originY);
								var t = this.getCenterPoint();
								(this.originX = 'center'), (this.originY = 'center'), (this.left = t.x), (this.top = t.y);
							},
							_resetOrigin: function () {
								var t = this.translateToOriginPoint(this.getCenterPoint(), this._originalOriginX, this._originalOriginY);
								(this.originX = this._originalOriginX),
									(this.originY = this._originalOriginY),
									(this.left = t.x),
									(this.top = t.y),
									(this._originalOriginX = null),
									(this._originalOriginY = null);
							},
							_getLeftTopCoords: function () {
								return this.translateToOriginPoint(this.getCenterPoint(), 'left', 'top');
							}
						});
					})(),
					(function () {
						function t(t) {
							return [new n.Point(t.tl.x, t.tl.y), new n.Point(t.tr.x, t.tr.y), new n.Point(t.br.x, t.br.y), new n.Point(t.bl.x, t.bl.y)];
						}
						var e = n.util,
							i = e.degreesToRadians,
							r = e.multiplyTransformMatrices,
							o = e.transformPoint;
						e.object.extend(n.Object.prototype, {
							oCoords: null,
							aCoords: null,
							lineCoords: null,
							ownMatrixCache: null,
							matrixCache: null,
							controls: {},
							_getCoords: function (t, e) {
								return e ? (t ? this.calcACoords() : this.calcLineCoords()) : ((this.aCoords && this.lineCoords) || this.setCoords(!0), t ? this.aCoords : this.lineCoords);
							},
							getCoords: function (e, i) {
								return t(this._getCoords(e, i));
							},
							intersectsWithRect: function (t, e, i, r) {
								var o = this.getCoords(i, r),
									s = n.Intersection.intersectPolygonRectangle(o, t, e);
								return 'Intersection' === s.status;
							},
							intersectsWithObject: function (t, e, i) {
								var r = n.Intersection.intersectPolygonPolygon(this.getCoords(e, i), t.getCoords(e, i));
								return 'Intersection' === r.status || t.isContainedWithinObject(this, e, i) || this.isContainedWithinObject(t, e, i);
							},
							isContainedWithinObject: function (t, e, i) {
								for (var n = this.getCoords(e, i), r = e ? t.aCoords : t.lineCoords, o = 0, s = t._getImageLines(r); o < 4; o++) if (!t.containsPoint(n[o], s)) return !1;
								return !0;
							},
							isContainedWithinRect: function (t, e, i, n) {
								var r = this.getBoundingRect(i, n);
								return r.left >= t.x && r.left + r.width <= e.x && r.top >= t.y && r.top + r.height <= e.y;
							},
							containsPoint: function (t, e, i, n) {
								var r = this._getCoords(i, n),
									o = ((e = e || this._getImageLines(r)), this._findCrossPoints(t, e));
								return 0 !== o && o % 2 === 1;
							},
							isOnScreen: function (t) {
								if (!this.canvas) return !1;
								var e = this.canvas.vptCoords.tl,
									i = this.canvas.vptCoords.br,
									n = this.getCoords(!0, t);
								return (
									!!n.some(function (t) {
										return t.x <= i.x && t.x >= e.x && t.y <= i.y && t.y >= e.y;
									}) ||
									!!this.intersectsWithRect(e, i, !0, t) ||
									this._containsCenterOfCanvas(e, i, t)
								);
							},
							_containsCenterOfCanvas: function (t, e, i) {
								var n = { x: (t.x + e.x) / 2, y: (t.y + e.y) / 2 };
								return !!this.containsPoint(n, null, !0, i);
							},
							isPartiallyOnScreen: function (t) {
								if (!this.canvas) return !1;
								var e = this.canvas.vptCoords.tl,
									i = this.canvas.vptCoords.br;
								if (this.intersectsWithRect(e, i, !0, t)) return !0;
								var n = this.getCoords(!0, t).every(function (t) {
									return (t.x >= i.x || t.x <= e.x) && (t.y >= i.y || t.y <= e.y);
								});
								return n && this._containsCenterOfCanvas(e, i, t);
							},
							_getImageLines: function (t) {
								var e = { topline: { o: t.tl, d: t.tr }, rightline: { o: t.tr, d: t.br }, bottomline: { o: t.br, d: t.bl }, leftline: { o: t.bl, d: t.tl } };
								return e;
							},
							_findCrossPoints: function (t, e) {
								var i,
									n,
									r,
									o,
									s,
									a,
									c = 0;
								for (var h in e)
									if (
										((a = e[h]),
										!(a.o.y < t.y && a.d.y < t.y) &&
											!(a.o.y >= t.y && a.d.y >= t.y) &&
											(a.o.x === a.d.x && a.o.x >= t.x
												? (s = a.o.x)
												: ((i = 0), (n = (a.d.y - a.o.y) / (a.d.x - a.o.x)), (r = t.y - i * t.x), (o = a.o.y - n * a.o.x), (s = -(r - o) / (i - n))),
											s >= t.x && (c += 1),
											2 === c))
									)
										break;
								return c;
							},
							getBoundingRect: function (t, i) {
								var n = this.getCoords(t, i);
								return e.makeBoundingBoxFromPoints(n);
							},
							getScaledWidth: function () {
								return this._getTransformedDimensions().x;
							},
							getScaledHeight: function () {
								return this._getTransformedDimensions().y;
							},
							_constrainScale: function (t) {
								return Math.abs(t) < this.minScaleLimit ? (t < 0 ? -this.minScaleLimit : this.minScaleLimit) : 0 === t ? 1e-4 : t;
							},
							scale: function (t) {
								return this._set('scaleX', t), this._set('scaleY', t), this.setCoords();
							},
							scaleToWidth: function (t, e) {
								var i = this.getBoundingRect(e).width / this.getScaledWidth();
								return this.scale(t / this.width / i);
							},
							scaleToHeight: function (t, e) {
								var i = this.getBoundingRect(e).height / this.getScaledHeight();
								return this.scale(t / this.height / i);
							},
							calcLineCoords: function () {
								var t = this.getViewportTransform(),
									n = this.padding,
									r = i(this.angle),
									s = e.cos(r),
									a = e.sin(r),
									c = s * n,
									h = a * n,
									l = c + h,
									u = c - h,
									f = this.calcACoords(),
									d = { tl: o(f.tl, t), tr: o(f.tr, t), bl: o(f.bl, t), br: o(f.br, t) };
								return n && ((d.tl.x -= u), (d.tl.y -= l), (d.tr.x += l), (d.tr.y -= u), (d.bl.x -= l), (d.bl.y += u), (d.br.x += u), (d.br.y += l)), d;
							},
							calcOCoords: function () {
								var t = this._calcRotateMatrix(),
									e = this._calcTranslateMatrix(),
									i = this.getViewportTransform(),
									n = r(i, e),
									o = r(n, t),
									s = ((o = r(o, [1 / i[0], 0, 0, 1 / i[3], 0, 0])), this._calculateCurrentDimensions()),
									a = {};
								return (
									this.forEachControl(function (t, e, i) {
										a[e] = t.positionHandler(s, o, i);
									}),
									a
								);
							},
							calcACoords: function () {
								var t = this._calcRotateMatrix(),
									e = this._calcTranslateMatrix(),
									i = r(e, t),
									n = this._getTransformedDimensions(),
									s = n.x / 2,
									a = n.y / 2;
								return { tl: o({ x: -s, y: -a }, i), tr: o({ x: s, y: -a }, i), bl: o({ x: -s, y: a }, i), br: o({ x: s, y: a }, i) };
							},
							setCoords: function (t) {
								return (
									(this.aCoords = this.calcACoords()),
									(this.lineCoords = this.group ? this.aCoords : this.calcLineCoords()),
									t || ((this.oCoords = this.calcOCoords()), this._setCornerCoords && this._setCornerCoords()),
									this
								);
							},
							_calcRotateMatrix: function () {
								return e.calcRotateMatrix(this);
							},
							_calcTranslateMatrix: function () {
								var t = this.getCenterPoint();
								return [1, 0, 0, 1, t.x, t.y];
							},
							transformMatrixKey: function (t) {
								var e = '_',
									i = '';
								return (
									!t && this.group && (i = this.group.transformMatrixKey(t) + e),
									i +
										this.top +
										e +
										this.left +
										e +
										this.scaleX +
										e +
										this.scaleY +
										e +
										this.skewX +
										e +
										this.skewY +
										e +
										this.angle +
										e +
										this.originX +
										e +
										this.originY +
										e +
										this.width +
										e +
										this.height +
										e +
										this.strokeWidth +
										this.flipX +
										this.flipY
								);
							},
							calcTransformMatrix: function (t) {
								var e = this.calcOwnMatrix();
								if (t || !this.group) return e;
								var i = this.transformMatrixKey(t),
									n = this.matrixCache || (this.matrixCache = {});
								return n.key === i ? n.value : (this.group && (e = r(this.group.calcTransformMatrix(!1), e)), (n.key = i), (n.value = e), e);
							},
							calcOwnMatrix: function () {
								var t = this.transformMatrixKey(!0),
									i = this.ownMatrixCache || (this.ownMatrixCache = {});
								if (i.key === t) return i.value;
								var n = this._calcTranslateMatrix(),
									r = {
										angle: this.angle,
										translateX: n[4],
										translateY: n[5],
										scaleX: this.scaleX,
										scaleY: this.scaleY,
										skewX: this.skewX,
										skewY: this.skewY,
										flipX: this.flipX,
										flipY: this.flipY
									};
								return (i.key = t), (i.value = e.composeMatrix(r)), i.value;
							},
							_getNonTransformedDimensions: function () {
								var t = this.strokeWidth,
									e = this.width + t,
									i = this.height + t;
								return { x: e, y: i };
							},
							_getTransformedDimensions: function (t, i) {
								'undefined' === typeof t && (t = this.skewX), 'undefined' === typeof i && (i = this.skewY);
								var n,
									r,
									o,
									s = 0 === t && 0 === i;
								if ((this.strokeUniform ? ((r = this.width), (o = this.height)) : ((n = this._getNonTransformedDimensions()), (r = n.x), (o = n.y)), s))
									return this._finalizeDimensions(r * this.scaleX, o * this.scaleY);
								var a = e.sizeAfterTransform(r, o, { scaleX: this.scaleX, scaleY: this.scaleY, skewX: t, skewY: i });
								return this._finalizeDimensions(a.x, a.y);
							},
							_finalizeDimensions: function (t, e) {
								return this.strokeUniform ? { x: t + this.strokeWidth, y: e + this.strokeWidth } : { x: t, y: e };
							},
							_calculateCurrentDimensions: function () {
								var t = this.getViewportTransform(),
									e = this._getTransformedDimensions(),
									i = o(e, t, !0);
								return i.scalarAdd(2 * this.padding);
							}
						});
					})(),
					n.util.object.extend(n.Object.prototype, {
						sendToBack: function () {
							return this.group ? n.StaticCanvas.prototype.sendToBack.call(this.group, this) : this.canvas && this.canvas.sendToBack(this), this;
						},
						bringToFront: function () {
							return this.group ? n.StaticCanvas.prototype.bringToFront.call(this.group, this) : this.canvas && this.canvas.bringToFront(this), this;
						},
						sendBackwards: function (t) {
							return this.group ? n.StaticCanvas.prototype.sendBackwards.call(this.group, this, t) : this.canvas && this.canvas.sendBackwards(this, t), this;
						},
						bringForward: function (t) {
							return this.group ? n.StaticCanvas.prototype.bringForward.call(this.group, this, t) : this.canvas && this.canvas.bringForward(this, t), this;
						},
						moveTo: function (t) {
							return this.group && 'activeSelection' !== this.group.type ? n.StaticCanvas.prototype.moveTo.call(this.group, this, t) : this.canvas && this.canvas.moveTo(this, t), this;
						}
					}),
					(function () {
						function t(t, e) {
							if (e) {
								if (e.toLive) return t + ': url(#SVGID_' + e.id + '); ';
								var i = new n.Color(e),
									r = t + ': ' + i.toRgb() + '; ',
									o = i.getAlpha();
								return 1 !== o && (r += t + '-opacity: ' + o.toString() + '; '), r;
							}
							return t + ': none; ';
						}
						var e = n.util.toFixed;
						n.util.object.extend(n.Object.prototype, {
							getSvgStyles: function (e) {
								var i = this.fillRule ? this.fillRule : 'nonzero',
									n = this.strokeWidth ? this.strokeWidth : '0',
									r = this.strokeDashArray ? this.strokeDashArray.join(' ') : 'none',
									o = this.strokeDashOffset ? this.strokeDashOffset : '0',
									s = this.strokeLineCap ? this.strokeLineCap : 'butt',
									a = this.strokeLineJoin ? this.strokeLineJoin : 'miter',
									c = this.strokeMiterLimit ? this.strokeMiterLimit : '4',
									h = 'undefined' !== typeof this.opacity ? this.opacity : '1',
									l = this.visible ? '' : ' visibility: hidden;',
									u = e ? '' : this.getSvgFilter(),
									f = t('fill', this.fill),
									d = t('stroke', this.stroke);
								return [
									d,
									'stroke-width: ',
									n,
									'; ',
									'stroke-dasharray: ',
									r,
									'; ',
									'stroke-linecap: ',
									s,
									'; ',
									'stroke-dashoffset: ',
									o,
									'; ',
									'stroke-linejoin: ',
									a,
									'; ',
									'stroke-miterlimit: ',
									c,
									'; ',
									f,
									'fill-rule: ',
									i,
									'; ',
									'opacity: ',
									h,
									';',
									u,
									l
								].join('');
							},
							getSvgSpanStyles: function (e, i) {
								var n = '; ',
									r = e.fontFamily ? 'font-family: ' + (-1 === e.fontFamily.indexOf("'") && -1 === e.fontFamily.indexOf('"') ? "'" + e.fontFamily + "'" : e.fontFamily) + n : '',
									o = e.strokeWidth ? 'stroke-width: ' + e.strokeWidth + n : '',
									s = ((r = r), e.fontSize ? 'font-size: ' + e.fontSize + 'px' + n : ''),
									a = e.fontStyle ? 'font-style: ' + e.fontStyle + n : '',
									c = e.fontWeight ? 'font-weight: ' + e.fontWeight + n : '',
									h = e.fill ? t('fill', e.fill) : '',
									l = e.stroke ? t('stroke', e.stroke) : '',
									u = this.getSvgTextDecoration(e),
									f = e.deltaY ? 'baseline-shift: ' + -e.deltaY + '; ' : '';
								return u && (u = 'text-decoration: ' + u + n), [l, o, r, s, a, c, u, h, f, i ? 'white-space: pre; ' : ''].join('');
							},
							getSvgTextDecoration: function (t) {
								return ['overline', 'underline', 'line-through']
									.filter(function (e) {
										return t[e.replace('-', '')];
									})
									.join(' ');
							},
							getSvgFilter: function () {
								return this.shadow ? 'filter: url(#SVGID_' + this.shadow.id + ');' : '';
							},
							getSvgCommons: function () {
								return [this.id ? 'id="' + this.id + '" ' : '', this.clipPath ? 'clip-path="url(#' + this.clipPath.clipPathId + ')" ' : ''].join('');
							},
							getSvgTransform: function (t, e) {
								var i = t ? this.calcTransformMatrix() : this.calcOwnMatrix(),
									r = 'transform="' + n.util.matrixToSVG(i);
								return r + (e || '') + '" ';
							},
							_setSVGBg: function (t) {
								if (this.backgroundColor) {
									var i = n.Object.NUM_FRACTION_DIGITS;
									t.push(
										'\t\t<rect ',
										this._getFillAttributes(this.backgroundColor),
										' x="',
										e(-this.width / 2, i),
										'" y="',
										e(-this.height / 2, i),
										'" width="',
										e(this.width, i),
										'" height="',
										e(this.height, i),
										'"></rect>\n'
									);
								}
							},
							toSVG: function (t) {
								return this._createBaseSVGMarkup(this._toSVG(t), { reviver: t });
							},
							toClipPathSVG: function (t) {
								return '\t' + this._createBaseClipPathSVGMarkup(this._toSVG(t), { reviver: t });
							},
							_createBaseClipPathSVGMarkup: function (t, e) {
								e = e || {};
								var i = e.reviver,
									n = e.additionalTransform || '',
									r = [this.getSvgTransform(!0, n), this.getSvgCommons()].join(''),
									o = t.indexOf('COMMON_PARTS');
								return (t[o] = r), i ? i(t.join('')) : t.join('');
							},
							_createBaseSVGMarkup: function (t, e) {
								e = e || {};
								var i,
									r,
									o = e.noStyle,
									s = e.reviver,
									a = o ? '' : 'style="' + this.getSvgStyles() + '" ',
									c = e.withShadow ? 'style="' + this.getSvgFilter() + '" ' : '',
									h = this.clipPath,
									l = this.strokeUniform ? 'vector-effect="non-scaling-stroke" ' : '',
									u = h && h.absolutePositioned,
									f = this.stroke,
									d = this.fill,
									p = this.shadow,
									g = [],
									v = t.indexOf('COMMON_PARTS'),
									m = e.additionalTransform;
								return (
									h && ((h.clipPathId = 'CLIPPATH_' + n.Object.__uid++), (r = '<clipPath id="' + h.clipPathId + '" >\n' + h.toClipPathSVG(s) + '</clipPath>\n')),
									u && g.push('<g ', c, this.getSvgCommons(), ' >\n'),
									g.push('<g ', this.getSvgTransform(!1), u ? '' : c + this.getSvgCommons(), ' >\n'),
									(i = [a, l, o ? '' : this.addPaintOrder(), ' ', m ? 'transform="' + m + '" ' : ''].join('')),
									(t[v] = i),
									d && d.toLive && g.push(d.toSVG(this)),
									f && f.toLive && g.push(f.toSVG(this)),
									p && g.push(p.toSVG(this)),
									h && g.push(r),
									g.push(t.join('')),
									g.push('</g>\n'),
									u && g.push('</g>\n'),
									s ? s(g.join('')) : g.join('')
								);
							},
							addPaintOrder: function () {
								return 'fill' !== this.paintFirst ? ' paint-order="' + this.paintFirst + '" ' : '';
							}
						});
					})(),
					(function () {
						var t = n.util.object.extend,
							e = 'stateProperties';
						function i(e, i, n) {
							var r = {},
								o = !0;
							n.forEach(function (t) {
								r[t] = e[t];
							}),
								t(e[i], r, o);
						}
						function r(t, e, i) {
							if (t === e) return !0;
							if (Array.isArray(t)) {
								if (!Array.isArray(e) || t.length !== e.length) return !1;
								for (var n = 0, o = t.length; n < o; n++) if (!r(t[n], e[n])) return !1;
								return !0;
							}
							if (t && 'object' === typeof t) {
								var s,
									a = Object.keys(t);
								if (!e || 'object' !== typeof e || (!i && a.length !== Object.keys(e).length)) return !1;
								for (n = 0, o = a.length; n < o; n++) if (((s = a[n]), 'canvas' !== s && 'group' !== s && !r(t[s], e[s]))) return !1;
								return !0;
							}
						}
						n.util.object.extend(n.Object.prototype, {
							hasStateChanged: function (t) {
								t = t || e;
								var i = '_' + t;
								return Object.keys(this[i]).length < this[t].length || !r(this[i], this, !0);
							},
							saveState: function (t) {
								var n = (t && t.propertySet) || e,
									r = '_' + n;
								return this[r] ? (i(this, r, this[n]), t && t.stateProperties && i(this, r, t.stateProperties), this) : this.setupState(t);
							},
							setupState: function (t) {
								t = t || {};
								var i = t.propertySet || e;
								return (t.propertySet = i), (this['_' + i] = {}), this.saveState(t), this;
							}
						});
					})(),
					(function () {
						var t = n.util.degreesToRadians;
						n.util.object.extend(n.Object.prototype, {
							_findTargetCorner: function (t, e) {
								if (!this.hasControls || this.group || !this.canvas || this.canvas._activeObject !== this) return !1;
								var i,
									n,
									r,
									o = t.x,
									s = t.y,
									a = Object.keys(this.oCoords),
									c = a.length - 1;
								for (this.__corner = 0; c >= 0; c--)
									if (
										((r = a[c]),
										this.isControlVisible(r) &&
											((n = this._getImageLines(e ? this.oCoords[r].touchCorner : this.oCoords[r].corner)),
											(i = this._findCrossPoints({ x: o, y: s }, n)),
											0 !== i && i % 2 === 1))
									)
										return (this.__corner = r), r;
								return !1;
							},
							forEachControl: function (t) {
								for (var e in this.controls) t(this.controls[e], e, this);
							},
							_setCornerCoords: function () {
								var t = this.oCoords;
								for (var e in t) {
									var i = this.controls[e];
									(t[e].corner = i.calcCornerCoords(this.angle, this.cornerSize, t[e].x, t[e].y, !1)),
										(t[e].touchCorner = i.calcCornerCoords(this.angle, this.touchCornerSize, t[e].x, t[e].y, !0));
								}
							},
							drawSelectionBackground: function (e) {
								if (!this.selectionBackgroundColor || (this.canvas && !this.canvas.interactive) || (this.canvas && this.canvas._activeObject !== this)) return this;
								e.save();
								var i = this.getCenterPoint(),
									n = this._calculateCurrentDimensions(),
									r = this.canvas.viewportTransform;
								return (
									e.translate(i.x, i.y),
									e.scale(1 / r[0], 1 / r[3]),
									e.rotate(t(this.angle)),
									(e.fillStyle = this.selectionBackgroundColor),
									e.fillRect(-n.x / 2, -n.y / 2, n.x, n.y),
									e.restore(),
									this
								);
							},
							drawBorders: function (t, e) {
								e = e || {};
								var i = this._calculateCurrentDimensions(),
									n = this.borderScaleFactor,
									r = i.x + n,
									o = i.y + n,
									s = 'undefined' !== typeof e.hasControls ? e.hasControls : this.hasControls,
									a = !1;
								return (
									t.save(),
									(t.strokeStyle = e.borderColor || this.borderColor),
									this._setLineDash(t, e.borderDashArray || this.borderDashArray),
									t.strokeRect(-r / 2, -o / 2, r, o),
									s &&
										(t.beginPath(),
										this.forEachControl(function (e, i, n) {
											e.withConnection && e.getVisibility(n, i) && ((a = !0), t.moveTo(e.x * r, e.y * o), t.lineTo(e.x * r + e.offsetX, e.y * o + e.offsetY));
										}),
										a && t.stroke()),
									t.restore(),
									this
								);
							},
							drawBordersInGroup: function (t, e, i) {
								i = i || {};
								var r = n.util.sizeAfterTransform(this.width, this.height, e),
									o = this.strokeWidth,
									s = this.strokeUniform,
									a = this.borderScaleFactor,
									c = r.x + o * (s ? this.canvas.getZoom() : e.scaleX) + a,
									h = r.y + o * (s ? this.canvas.getZoom() : e.scaleY) + a;
								return (
									t.save(),
									this._setLineDash(t, i.borderDashArray || this.borderDashArray),
									(t.strokeStyle = i.borderColor || this.borderColor),
									t.strokeRect(-c / 2, -h / 2, c, h),
									t.restore(),
									this
								);
							},
							drawControls: function (t, e) {
								(e = e || {}), t.save();
								var i,
									r,
									o = this.canvas.getRetinaScaling();
								return (
									t.setTransform(o, 0, 0, o, 0, 0),
									(t.strokeStyle = t.fillStyle = e.cornerColor || this.cornerColor),
									this.transparentCorners || (t.strokeStyle = e.cornerStrokeColor || this.cornerStrokeColor),
									this._setLineDash(t, e.cornerDashArray || this.cornerDashArray),
									this.setCoords(),
									this.group && (i = this.group.calcTransformMatrix()),
									this.forEachControl(function (o, s, a) {
										(r = a.oCoords[s]), o.getVisibility(a, s) && (i && (r = n.util.transformPoint(r, i)), o.render(t, r.x, r.y, e, a));
									}),
									t.restore(),
									this
								);
							},
							isControlVisible: function (t) {
								return this.controls[t] && this.controls[t].getVisibility(this, t);
							},
							setControlVisible: function (t, e) {
								return this._controlsVisibility || (this._controlsVisibility = {}), (this._controlsVisibility[t] = e), this;
							},
							setControlsVisibility: function (t) {
								for (var e in (t || (t = {}), t)) this.setControlVisible(e, t[e]);
								return this;
							},
							onDeselect: function () {},
							onSelect: function () {}
						});
					})(),
					n.util.object.extend(n.StaticCanvas.prototype, {
						FX_DURATION: 500,
						fxCenterObjectH: function (t, e) {
							e = e || {};
							var i = function () {},
								r = e.onComplete || i,
								o = e.onChange || i,
								s = this;
							return n.util.animate({
								target: this,
								startValue: t.left,
								endValue: this.getCenterPoint().x,
								duration: this.FX_DURATION,
								onChange: function (e) {
									t.set('left', e), s.requestRenderAll(), o();
								},
								onComplete: function () {
									t.setCoords(), r();
								}
							});
						},
						fxCenterObjectV: function (t, e) {
							e = e || {};
							var i = function () {},
								r = e.onComplete || i,
								o = e.onChange || i,
								s = this;
							return n.util.animate({
								target: this,
								startValue: t.top,
								endValue: this.getCenterPoint().y,
								duration: this.FX_DURATION,
								onChange: function (e) {
									t.set('top', e), s.requestRenderAll(), o();
								},
								onComplete: function () {
									t.setCoords(), r();
								}
							});
						},
						fxRemove: function (t, e) {
							e = e || {};
							var i = function () {},
								r = e.onComplete || i,
								o = e.onChange || i,
								s = this;
							return n.util.animate({
								target: this,
								startValue: t.opacity,
								endValue: 0,
								duration: this.FX_DURATION,
								onChange: function (e) {
									t.set('opacity', e), s.requestRenderAll(), o();
								},
								onComplete: function () {
									s.remove(t), r();
								}
							});
						}
					}),
					n.util.object.extend(n.Object.prototype, {
						animate: function () {
							if (arguments[0] && 'object' === typeof arguments[0]) {
								var t,
									e,
									i = [],
									n = [];
								for (t in arguments[0]) i.push(t);
								for (var r = 0, o = i.length; r < o; r++) (t = i[r]), (e = r !== o - 1), n.push(this._animate(t, arguments[0][t], arguments[1], e));
								return n;
							}
							return this._animate.apply(this, arguments);
						},
						_animate: function (t, e, i, r) {
							var o,
								s = this;
							(e = e.toString()), (i = i ? n.util.object.clone(i) : {}), ~t.indexOf('.') && (o = t.split('.'));
							var a = s.colorProperties.indexOf(t) > -1 || (o && s.colorProperties.indexOf(o[1]) > -1),
								c = o ? this.get(o[0])[o[1]] : this.get(t);
							'from' in i || (i.from = c), a || (e = ~e.indexOf('=') ? c + parseFloat(e.replace('=', '')) : parseFloat(e));
							var h = {
								target: this,
								startValue: i.from,
								endValue: e,
								byValue: i.by,
								easing: i.easing,
								duration: i.duration,
								abort:
									i.abort &&
									function (t, e, n) {
										return i.abort.call(s, t, e, n);
									},
								onChange: function (e, n, a) {
									o ? (s[o[0]][o[1]] = e) : s.set(t, e), r || (i.onChange && i.onChange(e, n, a));
								},
								onComplete: function (t, e, n) {
									r || (s.setCoords(), i.onComplete && i.onComplete(t, e, n));
								}
							};
							return a ? n.util.animateColor(h.startValue, h.endValue, h.duration, h) : n.util.animate(h);
						}
					}),
					(function (t) {
						'use strict';
						var e = t.fabric || (t.fabric = {}),
							i = e.util.object.extend,
							n = e.util.object.clone,
							r = { x1: 1, x2: 1, y1: 1, y2: 1 };
						function o(t, e) {
							var i = t.origin,
								n = t.axis1,
								r = t.axis2,
								o = t.dimension,
								s = e.nearest,
								a = e.center,
								c = e.farthest;
							return function () {
								switch (this.get(i)) {
									case s:
										return Math.min(this.get(n), this.get(r));
									case a:
										return Math.min(this.get(n), this.get(r)) + 0.5 * this.get(o);
									case c:
										return Math.max(this.get(n), this.get(r));
								}
							};
						}
						e.Line
							? e.warn('fabric.Line is already defined')
							: ((e.Line = e.util.createClass(e.Object, {
									type: 'line',
									x1: 0,
									y1: 0,
									x2: 0,
									y2: 0,
									cacheProperties: e.Object.prototype.cacheProperties.concat('x1', 'x2', 'y1', 'y2'),
									initialize: function (t, e) {
										t || (t = [0, 0, 0, 0]),
											this.callSuper('initialize', e),
											this.set('x1', t[0]),
											this.set('y1', t[1]),
											this.set('x2', t[2]),
											this.set('y2', t[3]),
											this._setWidthHeight(e);
									},
									_setWidthHeight: function (t) {
										t || (t = {}),
											(this.width = Math.abs(this.x2 - this.x1)),
											(this.height = Math.abs(this.y2 - this.y1)),
											(this.left = 'left' in t ? t.left : this._getLeftToOriginX()),
											(this.top = 'top' in t ? t.top : this._getTopToOriginY());
									},
									_set: function (t, e) {
										return this.callSuper('_set', t, e), 'undefined' !== typeof r[t] && this._setWidthHeight(), this;
									},
									_getLeftToOriginX: o({ origin: 'originX', axis1: 'x1', axis2: 'x2', dimension: 'width' }, { nearest: 'left', center: 'center', farthest: 'right' }),
									_getTopToOriginY: o({ origin: 'originY', axis1: 'y1', axis2: 'y2', dimension: 'height' }, { nearest: 'top', center: 'center', farthest: 'bottom' }),
									_render: function (t) {
										t.beginPath();
										var e = this.calcLinePoints();
										t.moveTo(e.x1, e.y1), t.lineTo(e.x2, e.y2), (t.lineWidth = this.strokeWidth);
										var i = t.strokeStyle;
										(t.strokeStyle = this.stroke || t.fillStyle), this.stroke && this._renderStroke(t), (t.strokeStyle = i);
									},
									_findCenterFromElement: function () {
										return { x: (this.x1 + this.x2) / 2, y: (this.y1 + this.y2) / 2 };
									},
									toObject: function (t) {
										return i(this.callSuper('toObject', t), this.calcLinePoints());
									},
									_getNonTransformedDimensions: function () {
										var t = this.callSuper('_getNonTransformedDimensions');
										return 'butt' === this.strokeLineCap && (0 === this.width && (t.y -= this.strokeWidth), 0 === this.height && (t.x -= this.strokeWidth)), t;
									},
									calcLinePoints: function () {
										var t = this.x1 <= this.x2 ? -1 : 1,
											e = this.y1 <= this.y2 ? -1 : 1,
											i = t * this.width * 0.5,
											n = e * this.height * 0.5,
											r = t * this.width * -0.5,
											o = e * this.height * -0.5;
										return { x1: i, x2: r, y1: n, y2: o };
									},
									_toSVG: function () {
										var t = this.calcLinePoints();
										return ['<line ', 'COMMON_PARTS', 'x1="', t.x1, '" y1="', t.y1, '" x2="', t.x2, '" y2="', t.y2, '" />\n'];
									}
							  })),
							  (e.Line.ATTRIBUTE_NAMES = e.SHARED_ATTRIBUTES.concat('x1 y1 x2 y2'.split(' '))),
							  (e.Line.fromElement = function (t, n, r) {
									r = r || {};
									var o = e.parseAttributes(t, e.Line.ATTRIBUTE_NAMES),
										s = [o.x1 || 0, o.y1 || 0, o.x2 || 0, o.y2 || 0];
									n(new e.Line(s, i(o, r)));
							  }),
							  (e.Line.fromObject = function (t, i) {
									function r(t) {
										delete t.points, i && i(t);
									}
									var o = n(t, !0);
									(o.points = [t.x1, t.y1, t.x2, t.y2]), e.Object._fromObject('Line', o, r, 'points');
							  }));
					})(e),
					(function (t) {
						'use strict';
						var e = t.fabric || (t.fabric = {}),
							i = e.util.degreesToRadians;
						function n(t) {
							return 'radius' in t && t.radius >= 0;
						}
						e.Circle
							? e.warn('fabric.Circle is already defined.')
							: ((e.Circle = e.util.createClass(e.Object, {
									type: 'circle',
									radius: 0,
									startAngle: 0,
									endAngle: 360,
									cacheProperties: e.Object.prototype.cacheProperties.concat('radius', 'startAngle', 'endAngle'),
									_set: function (t, e) {
										return this.callSuper('_set', t, e), 'radius' === t && this.setRadius(e), this;
									},
									toObject: function (t) {
										return this.callSuper('toObject', ['radius', 'startAngle', 'endAngle'].concat(t));
									},
									_toSVG: function () {
										var t,
											n = 0,
											r = 0,
											o = (this.endAngle - this.startAngle) % 360;
										if (0 === o) t = ['<circle ', 'COMMON_PARTS', 'cx="' + n + '" cy="' + r + '" ', 'r="', this.radius, '" />\n'];
										else {
											var s = i(this.startAngle),
												a = i(this.endAngle),
												c = this.radius,
												h = e.util.cos(s) * c,
												l = e.util.sin(s) * c,
												u = e.util.cos(a) * c,
												f = e.util.sin(a) * c,
												d = o > 180 ? '1' : '0';
											t = ['<path d="M ' + h + ' ' + l, ' A ' + c + ' ' + c, ' 0 ', +d + ' 1', ' ' + u + ' ' + f, '" ', 'COMMON_PARTS', ' />\n'];
										}
										return t;
									},
									_render: function (t) {
										t.beginPath(), t.arc(0, 0, this.radius, i(this.startAngle), i(this.endAngle), !1), this._renderPaintInOrder(t);
									},
									getRadiusX: function () {
										return this.get('radius') * this.get('scaleX');
									},
									getRadiusY: function () {
										return this.get('radius') * this.get('scaleY');
									},
									setRadius: function (t) {
										return (this.radius = t), this.set('width', 2 * t).set('height', 2 * t);
									}
							  })),
							  (e.Circle.ATTRIBUTE_NAMES = e.SHARED_ATTRIBUTES.concat('cx cy r'.split(' '))),
							  (e.Circle.fromElement = function (t, i) {
									var r = e.parseAttributes(t, e.Circle.ATTRIBUTE_NAMES);
									if (!n(r)) throw new Error('value of `r` attribute is required and can not be negative');
									(r.left = (r.left || 0) - r.radius), (r.top = (r.top || 0) - r.radius), i(new e.Circle(r));
							  }),
							  (e.Circle.fromObject = function (t, i) {
									e.Object._fromObject('Circle', t, i);
							  }));
					})(e),
					(function (t) {
						'use strict';
						var e = t.fabric || (t.fabric = {});
						e.Triangle
							? e.warn('fabric.Triangle is already defined')
							: ((e.Triangle = e.util.createClass(e.Object, {
									type: 'triangle',
									width: 100,
									height: 100,
									_render: function (t) {
										var e = this.width / 2,
											i = this.height / 2;
										t.beginPath(), t.moveTo(-e, i), t.lineTo(0, -i), t.lineTo(e, i), t.closePath(), this._renderPaintInOrder(t);
									},
									_toSVG: function () {
										var t = this.width / 2,
											e = this.height / 2,
											i = [-t + ' ' + e, '0 ' + -e, t + ' ' + e].join(',');
										return ['<polygon ', 'COMMON_PARTS', 'points="', i, '" />'];
									}
							  })),
							  (e.Triangle.fromObject = function (t, i) {
									return e.Object._fromObject('Triangle', t, i);
							  }));
					})(e),
					(function (t) {
						'use strict';
						var e = t.fabric || (t.fabric = {}),
							i = 2 * Math.PI;
						e.Ellipse
							? e.warn('fabric.Ellipse is already defined.')
							: ((e.Ellipse = e.util.createClass(e.Object, {
									type: 'ellipse',
									rx: 0,
									ry: 0,
									cacheProperties: e.Object.prototype.cacheProperties.concat('rx', 'ry'),
									initialize: function (t) {
										this.callSuper('initialize', t), this.set('rx', (t && t.rx) || 0), this.set('ry', (t && t.ry) || 0);
									},
									_set: function (t, e) {
										switch ((this.callSuper('_set', t, e), t)) {
											case 'rx':
												(this.rx = e), this.set('width', 2 * e);
												break;
											case 'ry':
												(this.ry = e), this.set('height', 2 * e);
												break;
										}
										return this;
									},
									getRx: function () {
										return this.get('rx') * this.get('scaleX');
									},
									getRy: function () {
										return this.get('ry') * this.get('scaleY');
									},
									toObject: function (t) {
										return this.callSuper('toObject', ['rx', 'ry'].concat(t));
									},
									_toSVG: function () {
										return ['<ellipse ', 'COMMON_PARTS', 'cx="0" cy="0" ', 'rx="', this.rx, '" ry="', this.ry, '" />\n'];
									},
									_render: function (t) {
										t.beginPath(), t.save(), t.transform(1, 0, 0, this.ry / this.rx, 0, 0), t.arc(0, 0, this.rx, 0, i, !1), t.restore(), this._renderPaintInOrder(t);
									}
							  })),
							  (e.Ellipse.ATTRIBUTE_NAMES = e.SHARED_ATTRIBUTES.concat('cx cy rx ry'.split(' '))),
							  (e.Ellipse.fromElement = function (t, i) {
									var n = e.parseAttributes(t, e.Ellipse.ATTRIBUTE_NAMES);
									(n.left = (n.left || 0) - n.rx), (n.top = (n.top || 0) - n.ry), i(new e.Ellipse(n));
							  }),
							  (e.Ellipse.fromObject = function (t, i) {
									e.Object._fromObject('Ellipse', t, i);
							  }));
					})(e),
					(function (t) {
						'use strict';
						var e = t.fabric || (t.fabric = {}),
							i = e.util.object.extend;
						e.Rect
							? e.warn('fabric.Rect is already defined')
							: ((e.Rect = e.util.createClass(e.Object, {
									stateProperties: e.Object.prototype.stateProperties.concat('rx', 'ry'),
									type: 'rect',
									rx: 0,
									ry: 0,
									cacheProperties: e.Object.prototype.cacheProperties.concat('rx', 'ry'),
									initialize: function (t) {
										this.callSuper('initialize', t), this._initRxRy();
									},
									_initRxRy: function () {
										this.rx && !this.ry ? (this.ry = this.rx) : this.ry && !this.rx && (this.rx = this.ry);
									},
									_render: function (t) {
										var e = this.rx ? Math.min(this.rx, this.width / 2) : 0,
											i = this.ry ? Math.min(this.ry, this.height / 2) : 0,
											n = this.width,
											r = this.height,
											o = -this.width / 2,
											s = -this.height / 2,
											a = 0 !== e || 0 !== i,
											c = 0.4477152502;
										t.beginPath(),
											t.moveTo(o + e, s),
											t.lineTo(o + n - e, s),
											a && t.bezierCurveTo(o + n - c * e, s, o + n, s + c * i, o + n, s + i),
											t.lineTo(o + n, s + r - i),
											a && t.bezierCurveTo(o + n, s + r - c * i, o + n - c * e, s + r, o + n - e, s + r),
											t.lineTo(o + e, s + r),
											a && t.bezierCurveTo(o + c * e, s + r, o, s + r - c * i, o, s + r - i),
											t.lineTo(o, s + i),
											a && t.bezierCurveTo(o, s + c * i, o + c * e, s, o + e, s),
											t.closePath(),
											this._renderPaintInOrder(t);
									},
									toObject: function (t) {
										return this.callSuper('toObject', ['rx', 'ry'].concat(t));
									},
									_toSVG: function () {
										var t = -this.width / 2,
											e = -this.height / 2;
										return ['<rect ', 'COMMON_PARTS', 'x="', t, '" y="', e, '" rx="', this.rx, '" ry="', this.ry, '" width="', this.width, '" height="', this.height, '" />\n'];
									}
							  })),
							  (e.Rect.ATTRIBUTE_NAMES = e.SHARED_ATTRIBUTES.concat('x y rx ry width height'.split(' '))),
							  (e.Rect.fromElement = function (t, n, r) {
									if (!t) return n(null);
									r = r || {};
									var o = e.parseAttributes(t, e.Rect.ATTRIBUTE_NAMES);
									(o.left = o.left || 0), (o.top = o.top || 0), (o.height = o.height || 0), (o.width = o.width || 0);
									var s = new e.Rect(i(r ? e.util.object.clone(r) : {}, o));
									(s.visible = s.visible && s.width > 0 && s.height > 0), n(s);
							  }),
							  (e.Rect.fromObject = function (t, i) {
									return e.Object._fromObject('Rect', t, i);
							  }));
					})(e),
					(function (t) {
						'use strict';
						var e = t.fabric || (t.fabric = {}),
							i = e.util.object.extend,
							n = e.util.array.min,
							r = e.util.array.max,
							o = e.util.toFixed,
							s = e.util.projectStrokeOnPoints;
						e.Polyline
							? e.warn('fabric.Polyline is already defined')
							: ((e.Polyline = e.util.createClass(e.Object, {
									type: 'polyline',
									points: null,
									exactBoundingBox: !1,
									cacheProperties: e.Object.prototype.cacheProperties.concat('points'),
									initialize: function (t, e) {
										(e = e || {}), (this.points = t || []), this.callSuper('initialize', e), this._setPositionDimensions(e);
									},
									_projectStrokeOnPoints: function () {
										return s(this.points, this, !0);
									},
									_setPositionDimensions: function (t) {
										var e,
											i = this._calcDimensions(t),
											n = this.exactBoundingBox ? this.strokeWidth : 0;
										(this.width = i.width - n),
											(this.height = i.height - n),
											t.fromSVG ||
												(e = this.translateToGivenOrigin(
													{ x: i.left - this.strokeWidth / 2 + n / 2, y: i.top - this.strokeWidth / 2 + n / 2 },
													'left',
													'top',
													this.originX,
													this.originY
												)),
											'undefined' === typeof t.left && (this.left = t.fromSVG ? i.left : e.x),
											'undefined' === typeof t.top && (this.top = t.fromSVG ? i.top : e.y),
											(this.pathOffset = { x: i.left + this.width / 2 + n / 2, y: i.top + this.height / 2 + n / 2 });
									},
									_calcDimensions: function () {
										var t = this.exactBoundingBox ? this._projectStrokeOnPoints() : this.points,
											e = n(t, 'x') || 0,
											i = n(t, 'y') || 0,
											o = r(t, 'x') || 0,
											s = r(t, 'y') || 0,
											a = o - e,
											c = s - i;
										return { left: e, top: i, width: a, height: c };
									},
									toObject: function (t) {
										return i(this.callSuper('toObject', t), { points: this.points.concat() });
									},
									_toSVG: function () {
										for (var t = [], i = this.pathOffset.x, n = this.pathOffset.y, r = e.Object.NUM_FRACTION_DIGITS, s = 0, a = this.points.length; s < a; s++)
											t.push(o(this.points[s].x - i, r), ',', o(this.points[s].y - n, r), ' ');
										return ['<' + this.type + ' ', 'COMMON_PARTS', 'points="', t.join(''), '" />\n'];
									},
									commonRender: function (t) {
										var e,
											i = this.points.length,
											n = this.pathOffset.x,
											r = this.pathOffset.y;
										if (!i || isNaN(this.points[i - 1].y)) return !1;
										t.beginPath(), t.moveTo(this.points[0].x - n, this.points[0].y - r);
										for (var o = 0; o < i; o++) (e = this.points[o]), t.lineTo(e.x - n, e.y - r);
										return !0;
									},
									_render: function (t) {
										this.commonRender(t) && this._renderPaintInOrder(t);
									},
									complexity: function () {
										return this.get('points').length;
									}
							  })),
							  (e.Polyline.ATTRIBUTE_NAMES = e.SHARED_ATTRIBUTES.concat()),
							  (e.Polyline.fromElementGenerator = function (t) {
									return function (n, r, o) {
										if (!n) return r(null);
										o || (o = {});
										var s = e.parsePointsAttribute(n.getAttribute('points')),
											a = e.parseAttributes(n, e[t].ATTRIBUTE_NAMES);
										(a.fromSVG = !0), r(new e[t](s, i(a, o)));
									};
							  }),
							  (e.Polyline.fromElement = e.Polyline.fromElementGenerator('Polyline')),
							  (e.Polyline.fromObject = function (t, i) {
									return e.Object._fromObject('Polyline', t, i, 'points');
							  }));
					})(e),
					(function (t) {
						'use strict';
						var e = t.fabric || (t.fabric = {}),
							i = e.util.projectStrokeOnPoints;
						e.Polygon
							? e.warn('fabric.Polygon is already defined')
							: ((e.Polygon = e.util.createClass(e.Polyline, {
									type: 'polygon',
									_projectStrokeOnPoints: function () {
										return i(this.points, this);
									},
									_render: function (t) {
										this.commonRender(t) && (t.closePath(), this._renderPaintInOrder(t));
									}
							  })),
							  (e.Polygon.ATTRIBUTE_NAMES = e.SHARED_ATTRIBUTES.concat()),
							  (e.Polygon.fromElement = e.Polyline.fromElementGenerator('Polygon')),
							  (e.Polygon.fromObject = function (t, i) {
									e.Object._fromObject('Polygon', t, i, 'points');
							  }));
					})(e),
					(function (t) {
						'use strict';
						var e = t.fabric || (t.fabric = {}),
							i = e.util.array.min,
							n = e.util.array.max,
							r = e.util.object.extend,
							o = e.util.object.clone,
							s = e.util.toFixed;
						e.Path
							? e.warn('fabric.Path is already defined')
							: ((e.Path = e.util.createClass(e.Object, {
									type: 'path',
									path: null,
									cacheProperties: e.Object.prototype.cacheProperties.concat('path', 'fillRule'),
									stateProperties: e.Object.prototype.stateProperties.concat('path'),
									initialize: function (t, e) {
										(e = o(e || {})), delete e.path, this.callSuper('initialize', e), this._setPath(t || [], e);
									},
									_setPath: function (t, i) {
										(this.path = e.util.makePathSimpler(Array.isArray(t) ? t : e.util.parsePath(t))), e.Polyline.prototype._setPositionDimensions.call(this, i || {});
									},
									_renderPathCommands: function (t) {
										var e,
											i = 0,
											n = 0,
											r = 0,
											o = 0,
											s = 0,
											a = 0,
											c = -this.pathOffset.x,
											h = -this.pathOffset.y;
										t.beginPath();
										for (var l = 0, u = this.path.length; l < u; ++l)
											switch (((e = this.path[l]), e[0])) {
												case 'L':
													(r = e[1]), (o = e[2]), t.lineTo(r + c, o + h);
													break;
												case 'M':
													(r = e[1]), (o = e[2]), (i = r), (n = o), t.moveTo(r + c, o + h);
													break;
												case 'C':
													(r = e[5]), (o = e[6]), (s = e[3]), (a = e[4]), t.bezierCurveTo(e[1] + c, e[2] + h, s + c, a + h, r + c, o + h);
													break;
												case 'Q':
													t.quadraticCurveTo(e[1] + c, e[2] + h, e[3] + c, e[4] + h), (r = e[3]), (o = e[4]), (s = e[1]), (a = e[2]);
													break;
												case 'z':
												case 'Z':
													(r = i), (o = n), t.closePath();
													break;
											}
									},
									_render: function (t) {
										this._renderPathCommands(t), this._renderPaintInOrder(t);
									},
									toString: function () {
										return '#<fabric.Path (' + this.complexity() + '): { "top": ' + this.top + ', "left": ' + this.left + ' }>';
									},
									toObject: function (t) {
										return r(this.callSuper('toObject', t), {
											path: this.path.map(function (t) {
												return t.slice();
											})
										});
									},
									toDatalessObject: function (t) {
										var e = this.toObject(['sourcePath'].concat(t));
										return e.sourcePath && delete e.path, e;
									},
									_toSVG: function () {
										var t = e.util.joinPath(this.path);
										return ['<path ', 'COMMON_PARTS', 'd="', t, '" stroke-linecap="round" ', '/>\n'];
									},
									_getOffsetTransform: function () {
										var t = e.Object.NUM_FRACTION_DIGITS;
										return ' translate(' + s(-this.pathOffset.x, t) + ', ' + s(-this.pathOffset.y, t) + ')';
									},
									toClipPathSVG: function (t) {
										var e = this._getOffsetTransform();
										return '\t' + this._createBaseClipPathSVGMarkup(this._toSVG(), { reviver: t, additionalTransform: e });
									},
									toSVG: function (t) {
										var e = this._getOffsetTransform();
										return this._createBaseSVGMarkup(this._toSVG(), { reviver: t, additionalTransform: e });
									},
									complexity: function () {
										return this.path.length;
									},
									_calcDimensions: function () {
										for (var t, r, o = [], s = [], a = 0, c = 0, h = 0, l = 0, u = 0, f = this.path.length; u < f; ++u) {
											switch (((t = this.path[u]), t[0])) {
												case 'L':
													(h = t[1]), (l = t[2]), (r = []);
													break;
												case 'M':
													(h = t[1]), (l = t[2]), (a = h), (c = l), (r = []);
													break;
												case 'C':
													(r = e.util.getBoundsOfCurve(h, l, t[1], t[2], t[3], t[4], t[5], t[6])), (h = t[5]), (l = t[6]);
													break;
												case 'Q':
													(r = e.util.getBoundsOfCurve(h, l, t[1], t[2], t[1], t[2], t[3], t[4])), (h = t[3]), (l = t[4]);
													break;
												case 'z':
												case 'Z':
													(h = a), (l = c);
													break;
											}
											r.forEach(function (t) {
												o.push(t.x), s.push(t.y);
											}),
												o.push(h),
												s.push(l);
										}
										var d = i(o) || 0,
											p = i(s) || 0,
											g = n(o) || 0,
											v = n(s) || 0,
											m = g - d,
											y = v - p;
										return { left: d, top: p, width: m, height: y };
									}
							  })),
							  (e.Path.fromObject = function (t, i) {
									if ('string' === typeof t.sourcePath) {
										var n = t.sourcePath;
										e.loadSVGFromURL(n, function (e) {
											var n = e[0];
											n.setOptions(t), i && i(n);
										});
									} else e.Object._fromObject('Path', t, i, 'path');
							  }),
							  (e.Path.ATTRIBUTE_NAMES = e.SHARED_ATTRIBUTES.concat(['d'])),
							  (e.Path.fromElement = function (t, i, n) {
									var o = e.parseAttributes(t, e.Path.ATTRIBUTE_NAMES);
									(o.fromSVG = !0), i(new e.Path(o.d, r(o, n)));
							  }));
					})(e),
					(function (t) {
						'use strict';
						var e = t.fabric || (t.fabric = {}),
							i = e.util.array.min,
							n = e.util.array.max;
						e.Group ||
							((e.Group = e.util.createClass(e.Object, e.Collection, {
								type: 'group',
								strokeWidth: 0,
								subTargetCheck: !1,
								cacheProperties: [],
								useSetOnGroup: !1,
								initialize: function (t, e, i) {
									(e = e || {}), (this._objects = []), i && this.callSuper('initialize', e), (this._objects = t || []);
									for (var n = this._objects.length; n--; ) this._objects[n].group = this;
									if (i) this._updateObjectsACoords();
									else {
										var r = e && e.centerPoint;
										void 0 !== e.originX && (this.originX = e.originX),
											void 0 !== e.originY && (this.originY = e.originY),
											r || this._calcBounds(),
											this._updateObjectsCoords(r),
											delete e.centerPoint,
											this.callSuper('initialize', e);
									}
									this.setCoords();
								},
								_updateObjectsACoords: function () {
									for (var t = !0, e = this._objects.length; e--; ) this._objects[e].setCoords(t);
								},
								_updateObjectsCoords: function (t) {
									t = t || this.getCenterPoint();
									for (var e = this._objects.length; e--; ) this._updateObjectCoords(this._objects[e], t);
								},
								_updateObjectCoords: function (t, e) {
									var i = t.left,
										n = t.top,
										r = !0;
									t.set({ left: i - e.x, top: n - e.y }), (t.group = this), t.setCoords(r);
								},
								toString: function () {
									return '#<fabric.Group: (' + this.complexity() + ')>';
								},
								addWithUpdate: function (t) {
									var i = !!this.group;
									return (
										this._restoreObjectsState(),
										e.util.resetObjectTransform(this),
										t && (i && e.util.removeTransformFromObject(t, this.group.calcTransformMatrix()), this._objects.push(t), (t.group = this), t._set('canvas', this.canvas)),
										this._calcBounds(),
										this._updateObjectsCoords(),
										(this.dirty = !0),
										i ? this.group.addWithUpdate() : this.setCoords(),
										this
									);
								},
								removeWithUpdate: function (t) {
									return (
										this._restoreObjectsState(),
										e.util.resetObjectTransform(this),
										this.remove(t),
										this._calcBounds(),
										this._updateObjectsCoords(),
										this.setCoords(),
										(this.dirty = !0),
										this
									);
								},
								_onObjectAdded: function (t) {
									(this.dirty = !0), (t.group = this), t._set('canvas', this.canvas);
								},
								_onObjectRemoved: function (t) {
									(this.dirty = !0), delete t.group;
								},
								_set: function (t, i) {
									var n = this._objects.length;
									if (this.useSetOnGroup) while (n--) this._objects[n].setOnGroup(t, i);
									if ('canvas' === t) while (n--) this._objects[n]._set(t, i);
									e.Object.prototype._set.call(this, t, i);
								},
								toObject: function (t) {
									var i = this.includeDefaultValues,
										n = this._objects
											.filter(function (t) {
												return !t.excludeFromExport;
											})
											.map(function (e) {
												var n = e.includeDefaultValues;
												e.includeDefaultValues = i;
												var r = e.toObject(t);
												return (e.includeDefaultValues = n), r;
											}),
										r = e.Object.prototype.toObject.call(this, t);
									return (r.objects = n), r;
								},
								toDatalessObject: function (t) {
									var i,
										n = this.sourcePath;
									if (n) i = n;
									else {
										var r = this.includeDefaultValues;
										i = this._objects.map(function (e) {
											var i = e.includeDefaultValues;
											e.includeDefaultValues = r;
											var n = e.toDatalessObject(t);
											return (e.includeDefaultValues = i), n;
										});
									}
									var o = e.Object.prototype.toDatalessObject.call(this, t);
									return (o.objects = i), o;
								},
								render: function (t) {
									(this._transformDone = !0), this.callSuper('render', t), (this._transformDone = !1);
								},
								shouldCache: function () {
									var t = e.Object.prototype.shouldCache.call(this);
									if (t) for (var i = 0, n = this._objects.length; i < n; i++) if (this._objects[i].willDrawShadow()) return (this.ownCaching = !1), !1;
									return t;
								},
								willDrawShadow: function () {
									if (e.Object.prototype.willDrawShadow.call(this)) return !0;
									for (var t = 0, i = this._objects.length; t < i; t++) if (this._objects[t].willDrawShadow()) return !0;
									return !1;
								},
								isOnACache: function () {
									return this.ownCaching || (this.group && this.group.isOnACache());
								},
								drawObject: function (t) {
									for (var e = 0, i = this._objects.length; e < i; e++) this._objects[e].render(t);
									this._drawClipPath(t, this.clipPath);
								},
								isCacheDirty: function (t) {
									if (this.callSuper('isCacheDirty', t)) return !0;
									if (!this.statefullCache) return !1;
									for (var e = 0, i = this._objects.length; e < i; e++)
										if (this._objects[e].isCacheDirty(!0)) {
											if (this._cacheCanvas) {
												var n = this.cacheWidth / this.zoomX,
													r = this.cacheHeight / this.zoomY;
												this._cacheContext.clearRect(-n / 2, -r / 2, n, r);
											}
											return !0;
										}
									return !1;
								},
								_restoreObjectsState: function () {
									var t = this.calcOwnMatrix();
									return (
										this._objects.forEach(function (i) {
											e.util.addTransformToObject(i, t), delete i.group, i.setCoords();
										}),
										this
									);
								},
								destroy: function () {
									return (
										this._objects.forEach(function (t) {
											t.set('dirty', !0);
										}),
										this._restoreObjectsState()
									);
								},
								dispose: function () {
									this.callSuper('dispose'),
										this.forEachObject(function (t) {
											t.dispose && t.dispose();
										}),
										(this._objects = []);
								},
								toActiveSelection: function () {
									if (this.canvas) {
										var t = this._objects,
											i = this.canvas;
										this._objects = [];
										var n = this.toObject();
										delete n.objects;
										var r = new e.ActiveSelection([]);
										return (
											r.set(n),
											(r.type = 'activeSelection'),
											i.remove(this),
											t.forEach(function (t) {
												(t.group = r), (t.dirty = !0), i.add(t);
											}),
											(r.canvas = i),
											(r._objects = t),
											(i._activeObject = r),
											r.setCoords(),
											r
										);
									}
								},
								ungroupOnCanvas: function () {
									return this._restoreObjectsState();
								},
								setObjectsCoords: function () {
									var t = !0;
									return (
										this.forEachObject(function (e) {
											e.setCoords(t);
										}),
										this
									);
								},
								_calcBounds: function (t) {
									for (var e, i, n, r, o = [], s = [], a = ['tr', 'br', 'bl', 'tl'], c = 0, h = this._objects.length, l = a.length; c < h; ++c) {
										for (e = this._objects[c], n = e.calcACoords(), r = 0; r < l; r++) (i = a[r]), o.push(n[i].x), s.push(n[i].y);
										e.aCoords = n;
									}
									this._getBounds(o, s, t);
								},
								_getBounds: function (t, r, o) {
									var s = new e.Point(i(t), i(r)),
										a = new e.Point(n(t), n(r)),
										c = s.y || 0,
										h = s.x || 0,
										l = a.x - s.x || 0,
										u = a.y - s.y || 0;
									(this.width = l), (this.height = u), o || this.setPositionByOrigin({ x: h, y: c }, 'left', 'top');
								},
								_toSVG: function (t) {
									for (var e = ['<g ', 'COMMON_PARTS', ' >\n'], i = 0, n = this._objects.length; i < n; i++) e.push('\t\t', this._objects[i].toSVG(t));
									return e.push('</g>\n'), e;
								},
								getSvgStyles: function () {
									var t = 'undefined' !== typeof this.opacity && 1 !== this.opacity ? 'opacity: ' + this.opacity + ';' : '',
										e = this.visible ? '' : ' visibility: hidden;';
									return [t, this.getSvgFilter(), e].join('');
								},
								toClipPathSVG: function (t) {
									for (var e = [], i = 0, n = this._objects.length; i < n; i++) e.push('\t', this._objects[i].toClipPathSVG(t));
									return this._createBaseClipPathSVGMarkup(e, { reviver: t });
								}
							})),
							(e.Group.fromObject = function (t, i) {
								var n = t.objects,
									r = e.util.object.clone(t, !0);
								delete r.objects,
									'string' !== typeof n
										? e.util.enlivenObjects(n, function (n) {
												var r = e.util.object.clone(t, !0);
												delete r.objects,
													e.util.enlivenObjectEnlivables(t, r, function () {
														i && i(new e.Group(n, r, !0));
													});
										  })
										: e.loadSVGFromURL(n, function (o) {
												var s = e.util.groupSVGElements(o, t, n);
												s.set(r), i && i(s);
										  });
							}));
					})(e),
					(function (t) {
						'use strict';
						var e = t.fabric || (t.fabric = {});
						e.ActiveSelection ||
							((e.ActiveSelection = e.util.createClass(e.Group, {
								type: 'activeSelection',
								initialize: function (t, i) {
									(i = i || {}), (this._objects = t || []);
									for (var n = this._objects.length; n--; ) this._objects[n].group = this;
									i.originX && (this.originX = i.originX),
										i.originY && (this.originY = i.originY),
										this._calcBounds(),
										this._updateObjectsCoords(),
										e.Object.prototype.initialize.call(this, i),
										this.setCoords();
								},
								toGroup: function () {
									var t = this._objects.concat();
									this._objects = [];
									var i = e.Object.prototype.toObject.call(this),
										n = new e.Group([]);
									if (
										(delete i.type,
										n.set(i),
										t.forEach(function (t) {
											t.canvas.remove(t), (t.group = n);
										}),
										(n._objects = t),
										!this.canvas)
									)
										return n;
									var r = this.canvas;
									return r.add(n), (r._activeObject = n), n.setCoords(), n;
								},
								onDeselect: function () {
									return this.destroy(), !1;
								},
								toString: function () {
									return '#<fabric.ActiveSelection: (' + this.complexity() + ')>';
								},
								shouldCache: function () {
									return !1;
								},
								isOnACache: function () {
									return !1;
								},
								_renderControls: function (t, e, i) {
									t.save(),
										(t.globalAlpha = this.isMoving ? this.borderOpacityWhenMoving : 1),
										this.callSuper('_renderControls', t, e),
										(i = i || {}),
										'undefined' === typeof i.hasControls && (i.hasControls = !1),
										(i.forActiveSelection = !0);
									for (var n = 0, r = this._objects.length; n < r; n++) this._objects[n]._renderControls(t, i);
									t.restore();
								}
							})),
							(e.ActiveSelection.fromObject = function (t, i) {
								e.util.enlivenObjects(t.objects, function (n) {
									delete t.objects, i && i(new e.ActiveSelection(n, t, !0));
								});
							}));
					})(e),
					(function (t) {
						'use strict';
						var e = n.util.object.extend;
						t.fabric || (t.fabric = {}),
							t.fabric.Image
								? n.warn('fabric.Image is already defined.')
								: ((n.Image = n.util.createClass(n.Object, {
										type: 'image',
										strokeWidth: 0,
										srcFromAttribute: !1,
										_lastScaleX: 1,
										_lastScaleY: 1,
										_filterScalingX: 1,
										_filterScalingY: 1,
										minimumScaleTrigger: 0.5,
										stateProperties: n.Object.prototype.stateProperties.concat('cropX', 'cropY'),
										cacheProperties: n.Object.prototype.cacheProperties.concat('cropX', 'cropY'),
										cacheKey: '',
										cropX: 0,
										cropY: 0,
										imageSmoothing: !0,
										initialize: function (t, e) {
											e || (e = {}), (this.filters = []), (this.cacheKey = 'texture' + n.Object.__uid++), this.callSuper('initialize', e), this._initElement(t, e);
										},
										getElement: function () {
											return this._element || {};
										},
										setElement: function (t, e) {
											return (
												this.removeTexture(this.cacheKey),
												this.removeTexture(this.cacheKey + '_filtered'),
												(this._element = t),
												(this._originalElement = t),
												this._initConfig(e),
												0 !== this.filters.length && this.applyFilters(),
												this.resizeFilter && this.applyResizeFilters(),
												this
											);
										},
										removeTexture: function (t) {
											var e = n.filterBackend;
											e && e.evictCachesForKey && e.evictCachesForKey(t);
										},
										dispose: function () {
											this.callSuper('dispose'),
												this.removeTexture(this.cacheKey),
												this.removeTexture(this.cacheKey + '_filtered'),
												(this._cacheContext = void 0),
												['_originalElement', '_element', '_filteredEl', '_cacheCanvas'].forEach(
													function (t) {
														n.util.cleanUpJsdomNode(this[t]), (this[t] = void 0);
													}.bind(this)
												);
										},
										getCrossOrigin: function () {
											return this._originalElement && (this._originalElement.crossOrigin || null);
										},
										getOriginalSize: function () {
											var t = this.getElement();
											return { width: t.naturalWidth || t.width, height: t.naturalHeight || t.height };
										},
										_stroke: function (t) {
											if (this.stroke && 0 !== this.strokeWidth) {
												var e = this.width / 2,
													i = this.height / 2;
												t.beginPath(), t.moveTo(-e, -i), t.lineTo(e, -i), t.lineTo(e, i), t.lineTo(-e, i), t.lineTo(-e, -i), t.closePath();
											}
										},
										toObject: function (t) {
											var i = [];
											this.filters.forEach(function (t) {
												t && i.push(t.toObject());
											});
											var n = e(this.callSuper('toObject', ['cropX', 'cropY'].concat(t)), { src: this.getSrc(), crossOrigin: this.getCrossOrigin(), filters: i });
											return this.resizeFilter && (n.resizeFilter = this.resizeFilter.toObject()), n;
										},
										hasCrop: function () {
											return this.cropX || this.cropY || this.width < this._element.width || this.height < this._element.height;
										},
										_toSVG: function () {
											var t,
												e = [],
												i = [],
												r = this._element,
												o = -this.width / 2,
												s = -this.height / 2,
												a = '',
												c = '';
											if (!r) return [];
											if (this.hasCrop()) {
												var h = n.Object.__uid++;
												e.push(
													'<clipPath id="imageCrop_' + h + '">\n',
													'\t<rect x="' + o + '" y="' + s + '" width="' + this.width + '" height="' + this.height + '" />\n',
													'</clipPath>\n'
												),
													(a = ' clip-path="url(#imageCrop_' + h + ')" ');
											}
											if (
												(this.imageSmoothing || (c = '" image-rendering="optimizeSpeed'),
												i.push(
													'\t<image ',
													'COMMON_PARTS',
													'xlink:href="',
													this.getSvgSrc(!0),
													'" x="',
													o - this.cropX,
													'" y="',
													s - this.cropY,
													'" width="',
													r.width || r.naturalWidth,
													'" height="',
													r.height || r.height,
													c,
													'"',
													a,
													'></image>\n'
												),
												this.stroke || this.strokeDashArray)
											) {
												var l = this.fill;
												(this.fill = null),
													(t = ['\t<rect ', 'x="', o, '" y="', s, '" width="', this.width, '" height="', this.height, '" style="', this.getSvgStyles(), '"/>\n']),
													(this.fill = l);
											}
											return (e = 'fill' !== this.paintFirst ? e.concat(t, i) : e.concat(i, t)), e;
										},
										getSrc: function (t) {
											var e = t ? this._element : this._originalElement;
											return e ? (e.toDataURL ? e.toDataURL() : this.srcFromAttribute ? e.getAttribute('src') : e.src) : this.src || '';
										},
										setSrc: function (t, e, i) {
											return (
												n.util.loadImage(
													t,
													function (t, n) {
														this.setElement(t, i), this._setWidthHeight(), e && e(this, n);
													},
													this,
													i && i.crossOrigin
												),
												this
											);
										},
										toString: function () {
											return '#<fabric.Image: { src: "' + this.getSrc() + '" }>';
										},
										applyResizeFilters: function () {
											var t = this.resizeFilter,
												e = this.minimumScaleTrigger,
												i = this.getTotalObjectScaling(),
												r = i.scaleX,
												o = i.scaleY,
												s = this._filteredEl || this._originalElement;
											if ((this.group && this.set('dirty', !0), !t || (r > e && o > e)))
												return (this._element = s), (this._filterScalingX = 1), (this._filterScalingY = 1), (this._lastScaleX = r), void (this._lastScaleY = o);
											n.filterBackend || (n.filterBackend = n.initFilterBackend());
											var a = n.util.createCanvasElement(),
												c = this._filteredEl ? this.cacheKey + '_filtered' : this.cacheKey,
												h = s.width,
												l = s.height;
											(a.width = h),
												(a.height = l),
												(this._element = a),
												(this._lastScaleX = t.scaleX = r),
												(this._lastScaleY = t.scaleY = o),
												n.filterBackend.applyFilters([t], s, h, l, this._element, c),
												(this._filterScalingX = a.width / this._originalElement.width),
												(this._filterScalingY = a.height / this._originalElement.height);
										},
										applyFilters: function (t) {
											if (
												((t = t || this.filters || []),
												(t = t.filter(function (t) {
													return t && !t.isNeutralState();
												})),
												this.set('dirty', !0),
												this.removeTexture(this.cacheKey + '_filtered'),
												0 === t.length)
											)
												return (this._element = this._originalElement), (this._filteredEl = null), (this._filterScalingX = 1), (this._filterScalingY = 1), this;
											var e = this._originalElement,
												i = e.naturalWidth || e.width,
												r = e.naturalHeight || e.height;
											if (this._element === this._originalElement) {
												var o = n.util.createCanvasElement();
												(o.width = i), (o.height = r), (this._element = o), (this._filteredEl = o);
											} else (this._element = this._filteredEl), this._filteredEl.getContext('2d').clearRect(0, 0, i, r), (this._lastScaleX = 1), (this._lastScaleY = 1);
											return (
												n.filterBackend || (n.filterBackend = n.initFilterBackend()),
												n.filterBackend.applyFilters(t, this._originalElement, i, r, this._element, this.cacheKey),
												(this._originalElement.width === this._element.width && this._originalElement.height === this._element.height) ||
													((this._filterScalingX = this._element.width / this._originalElement.width),
													(this._filterScalingY = this._element.height / this._originalElement.height)),
												this
											);
										},
										_render: function (t) {
											n.util.setImageSmoothing(t, this.imageSmoothing),
												!0 !== this.isMoving && this.resizeFilter && this._needsResize() && this.applyResizeFilters(),
												this._stroke(t),
												this._renderPaintInOrder(t);
										},
										drawCacheOnCanvas: function (t) {
											n.util.setImageSmoothing(t, this.imageSmoothing), n.Object.prototype.drawCacheOnCanvas.call(this, t);
										},
										shouldCache: function () {
											return this.needsItsOwnCache();
										},
										_renderFill: function (t) {
											var e = this._element;
											if (e) {
												var i = this._filterScalingX,
													n = this._filterScalingY,
													r = this.width,
													o = this.height,
													s = Math.min,
													a = Math.max,
													c = a(this.cropX, 0),
													h = a(this.cropY, 0),
													l = e.naturalWidth || e.width,
													u = e.naturalHeight || e.height,
													f = c * i,
													d = h * n,
													p = s(r * i, l - f),
													g = s(o * n, u - d),
													v = -r / 2,
													m = -o / 2,
													y = s(r, l / i - c),
													b = s(o, u / n - h);
												e && t.drawImage(e, f, d, p, g, v, m, y, b);
											}
										},
										_needsResize: function () {
											var t = this.getTotalObjectScaling();
											return t.scaleX !== this._lastScaleX || t.scaleY !== this._lastScaleY;
										},
										_resetWidthHeight: function () {
											this.set(this.getOriginalSize());
										},
										_initElement: function (t, e) {
											this.setElement(n.util.getById(t), e), n.util.addClass(this.getElement(), n.Image.CSS_CANVAS);
										},
										_initConfig: function (t) {
											t || (t = {}), this.setOptions(t), this._setWidthHeight(t);
										},
										_initFilters: function (t, e) {
											t && t.length
												? n.util.enlivenObjects(
														t,
														function (t) {
															e && e(t);
														},
														'fabric.Image.filters'
												  )
												: e && e();
										},
										_setWidthHeight: function (t) {
											t || (t = {});
											var e = this.getElement();
											(this.width = t.width || e.naturalWidth || e.width || 0), (this.height = t.height || e.naturalHeight || e.height || 0);
										},
										parsePreserveAspectRatioAttribute: function () {
											var t,
												e = n.util.parsePreserveAspectRatioAttribute(this.preserveAspectRatio || ''),
												i = this._element.width,
												r = this._element.height,
												o = 1,
												s = 1,
												a = 0,
												c = 0,
												h = 0,
												l = 0,
												u = this.width,
												f = this.height,
												d = { width: u, height: f };
											return (
												!e || ('none' === e.alignX && 'none' === e.alignY)
													? ((o = u / i), (s = f / r))
													: ('meet' === e.meetOrSlice &&
															((o = s = n.util.findScaleToFit(this._element, d)),
															(t = (u - i * o) / 2),
															'Min' === e.alignX && (a = -t),
															'Max' === e.alignX && (a = t),
															(t = (f - r * s) / 2),
															'Min' === e.alignY && (c = -t),
															'Max' === e.alignY && (c = t)),
													  'slice' === e.meetOrSlice &&
															((o = s = n.util.findScaleToCover(this._element, d)),
															(t = i - u / o),
															'Mid' === e.alignX && (h = t / 2),
															'Max' === e.alignX && (h = t),
															(t = r - f / s),
															'Mid' === e.alignY && (l = t / 2),
															'Max' === e.alignY && (l = t),
															(i = u / o),
															(r = f / s))),
												{ width: i, height: r, scaleX: o, scaleY: s, offsetLeft: a, offsetTop: c, cropX: h, cropY: l }
											);
										}
								  })),
								  (n.Image.CSS_CANVAS = 'canvas-img'),
								  (n.Image.prototype.getSvgSrc = n.Image.prototype.getSrc),
								  (n.Image.fromObject = function (t, e) {
										var i = n.util.object.clone(t);
										n.util.loadImage(
											i.src,
											function (t, r) {
												r
													? e && e(null, !0)
													: n.Image.prototype._initFilters.call(i, i.filters, function (r) {
															(i.filters = r || []),
																n.Image.prototype._initFilters.call(i, [i.resizeFilter], function (r) {
																	(i.resizeFilter = r[0]),
																		n.util.enlivenObjectEnlivables(i, i, function () {
																			var r = new n.Image(t, i);
																			e(r, !1);
																		});
																});
													  });
											},
											null,
											i.crossOrigin
										);
								  }),
								  (n.Image.fromURL = function (t, e, i) {
										n.util.loadImage(
											t,
											function (t, r) {
												e && e(new n.Image(t, i), r);
											},
											null,
											i && i.crossOrigin
										);
								  }),
								  (n.Image.ATTRIBUTE_NAMES = n.SHARED_ATTRIBUTES.concat('x y width height preserveAspectRatio xlink:href crossOrigin image-rendering'.split(' '))),
								  (n.Image.fromElement = function (t, i, r) {
										var o = n.parseAttributes(t, n.Image.ATTRIBUTE_NAMES);
										n.Image.fromURL(o['xlink:href'], i, e(r ? n.util.object.clone(r) : {}, o));
								  }));
					})(e),
					n.util.object.extend(n.Object.prototype, {
						_getAngleValueForStraighten: function () {
							var t = this.angle % 360;
							return t > 0 ? 90 * Math.round((t - 1) / 90) : 90 * Math.round(t / 90);
						},
						straighten: function () {
							return this.rotate(this._getAngleValueForStraighten());
						},
						fxStraighten: function (t) {
							t = t || {};
							var e = function () {},
								i = t.onComplete || e,
								r = t.onChange || e,
								o = this;
							return n.util.animate({
								target: this,
								startValue: this.get('angle'),
								endValue: this._getAngleValueForStraighten(),
								duration: this.FX_DURATION,
								onChange: function (t) {
									o.rotate(t), r();
								},
								onComplete: function () {
									o.setCoords(), i();
								}
							});
						}
					}),
					n.util.object.extend(n.StaticCanvas.prototype, {
						straightenObject: function (t) {
							return t.straighten(), this.requestRenderAll(), this;
						},
						fxStraightenObject: function (t) {
							return t.fxStraighten({ onChange: this.requestRenderAllBound });
						}
					}),
					(function () {
						'use strict';
						function t(t, e) {
							var i = 'precision ' + e + ' float;\nvoid main(){}',
								n = t.createShader(t.FRAGMENT_SHADER);
							return t.shaderSource(n, i), t.compileShader(n), !!t.getShaderParameter(n, t.COMPILE_STATUS);
						}
						function e(t) {
							t && t.tileSize && (this.tileSize = t.tileSize), this.setupGLContext(this.tileSize, this.tileSize), this.captureGPUInfo();
						}
						(n.isWebglSupported = function (e) {
							if (n.isLikelyNode) return !1;
							e = e || n.WebglFilterBackend.prototype.tileSize;
							var i = document.createElement('canvas'),
								r = i.getContext('webgl') || i.getContext('experimental-webgl'),
								o = !1;
							if (r) {
								(n.maxTextureSize = r.getParameter(r.MAX_TEXTURE_SIZE)), (o = n.maxTextureSize >= e);
								for (var s = ['highp', 'mediump', 'lowp'], a = 0; a < 3; a++)
									if (t(r, s[a])) {
										n.webGlPrecision = s[a];
										break;
									}
							}
							return (this.isSupported = o), o;
						}),
							(n.WebglFilterBackend = e),
							(e.prototype = {
								tileSize: 2048,
								resources: {},
								setupGLContext: function (t, e) {
									this.dispose(), this.createWebGLCanvas(t, e), (this.aPosition = new Float32Array([0, 0, 0, 1, 1, 0, 1, 1])), this.chooseFastestCopyGLTo2DMethod(t, e);
								},
								chooseFastestCopyGLTo2DMethod: function (t, e) {
									var i,
										r = 'undefined' !== typeof window.performance;
									try {
										new ImageData(1, 1), (i = !0);
									} catch (g) {
										i = !1;
									}
									var o = 'undefined' !== typeof ArrayBuffer,
										s = 'undefined' !== typeof Uint8ClampedArray;
									if (r && i && o && s) {
										var h = n.util.createCanvasElement(),
											l = new ArrayBuffer(t * e * 4);
										if (n.forceGLPutImageData) return (this.imageBuffer = l), void (this.copyGLTo2D = c);
										var u,
											f,
											d,
											p = { imageBuffer: l, destinationWidth: t, destinationHeight: e, targetCanvas: h };
										(h.width = t),
											(h.height = e),
											(u = window.performance.now()),
											a.call(p, this.gl, p),
											(f = window.performance.now() - u),
											(u = window.performance.now()),
											c.call(p, this.gl, p),
											(d = window.performance.now() - u),
											f > d ? ((this.imageBuffer = l), (this.copyGLTo2D = c)) : (this.copyGLTo2D = a);
									}
								},
								createWebGLCanvas: function (t, e) {
									var i = n.util.createCanvasElement();
									(i.width = t), (i.height = e);
									var r = { alpha: !0, premultipliedAlpha: !1, depth: !1, stencil: !1, antialias: !1 },
										o = i.getContext('webgl', r);
									o || (o = i.getContext('experimental-webgl', r)), o && (o.clearColor(0, 0, 0, 0), (this.canvas = i), (this.gl = o));
								},
								applyFilters: function (t, e, i, n, r, o) {
									var a,
										c = this.gl;
									o && (a = this.getCachedTexture(o, e));
									var h = {
											originalWidth: e.width || e.originalWidth,
											originalHeight: e.height || e.originalHeight,
											sourceWidth: i,
											sourceHeight: n,
											destinationWidth: i,
											destinationHeight: n,
											context: c,
											sourceTexture: this.createTexture(c, i, n, !a && e),
											targetTexture: this.createTexture(c, i, n),
											originalTexture: a || this.createTexture(c, i, n, !a && e),
											passes: t.length,
											webgl: !0,
											aPosition: this.aPosition,
											programCache: this.programCache,
											pass: 0,
											filterBackend: this,
											targetCanvas: r
										},
										l = c.createFramebuffer();
									return (
										c.bindFramebuffer(c.FRAMEBUFFER, l),
										t.forEach(function (t) {
											t && t.applyTo(h);
										}),
										s(h),
										this.copyGLTo2D(c, h),
										c.bindTexture(c.TEXTURE_2D, null),
										c.deleteTexture(h.sourceTexture),
										c.deleteTexture(h.targetTexture),
										c.deleteFramebuffer(l),
										r.getContext('2d').setTransform(1, 0, 0, 1, 0, 0),
										h
									);
								},
								dispose: function () {
									this.canvas && ((this.canvas = null), (this.gl = null)), this.clearWebGLCaches();
								},
								clearWebGLCaches: function () {
									(this.programCache = {}), (this.textureCache = {});
								},
								createTexture: function (t, e, i, n) {
									var r = t.createTexture();
									return (
										t.bindTexture(t.TEXTURE_2D, r),
										t.texParameteri(t.TEXTURE_2D, t.TEXTURE_MAG_FILTER, t.NEAREST),
										t.texParameteri(t.TEXTURE_2D, t.TEXTURE_MIN_FILTER, t.NEAREST),
										t.texParameteri(t.TEXTURE_2D, t.TEXTURE_WRAP_S, t.CLAMP_TO_EDGE),
										t.texParameteri(t.TEXTURE_2D, t.TEXTURE_WRAP_T, t.CLAMP_TO_EDGE),
										n ? t.texImage2D(t.TEXTURE_2D, 0, t.RGBA, t.RGBA, t.UNSIGNED_BYTE, n) : t.texImage2D(t.TEXTURE_2D, 0, t.RGBA, e, i, 0, t.RGBA, t.UNSIGNED_BYTE, null),
										r
									);
								},
								getCachedTexture: function (t, e) {
									if (this.textureCache[t]) return this.textureCache[t];
									var i = this.createTexture(this.gl, e.width, e.height, e);
									return (this.textureCache[t] = i), i;
								},
								evictCachesForKey: function (t) {
									this.textureCache[t] && (this.gl.deleteTexture(this.textureCache[t]), delete this.textureCache[t]);
								},
								copyGLTo2D: a,
								captureGPUInfo: function () {
									if (this.gpuInfo) return this.gpuInfo;
									var t = this.gl,
										e = { renderer: '', vendor: '' };
									if (!t) return e;
									var i = t.getExtension('WEBGL_debug_renderer_info');
									if (i) {
										var n = t.getParameter(i.UNMASKED_RENDERER_WEBGL),
											r = t.getParameter(i.UNMASKED_VENDOR_WEBGL);
										n && (e.renderer = n.toLowerCase()), r && (e.vendor = r.toLowerCase());
									}
									return (this.gpuInfo = e), e;
								}
							});
					})(),
					(function () {
						'use strict';
						var t = function () {};
						function e() {}
						(n.Canvas2dFilterBackend = e),
							(e.prototype = {
								evictCachesForKey: t,
								dispose: t,
								clearWebGLCaches: t,
								resources: {},
								applyFilters: function (t, e, i, n, r) {
									var o = r.getContext('2d');
									o.drawImage(e, 0, 0, i, n);
									var s = o.getImageData(0, 0, i, n),
										a = o.getImageData(0, 0, i, n),
										c = { sourceWidth: i, sourceHeight: n, imageData: s, originalEl: e, originalImageData: a, canvasEl: r, ctx: o, filterBackend: this };
									return (
										t.forEach(function (t) {
											t.applyTo(c);
										}),
										(c.imageData.width === i && c.imageData.height === n) || ((r.width = c.imageData.width), (r.height = c.imageData.height)),
										o.putImageData(c.imageData, 0, 0),
										c
									);
								}
							});
					})(),
					(n.Image = n.Image || {}),
					(n.Image.filters = n.Image.filters || {}),
					(n.Image.filters.BaseFilter = n.util.createClass({
						type: 'BaseFilter',
						vertexSource: 'attribute vec2 aPosition;\nvarying vec2 vTexCoord;\nvoid main() {\nvTexCoord = aPosition;\ngl_Position = vec4(aPosition * 2.0 - 1.0, 0.0, 1.0);\n}',
						fragmentSource: 'precision highp float;\nvarying vec2 vTexCoord;\nuniform sampler2D uTexture;\nvoid main() {\ngl_FragColor = texture2D(uTexture, vTexCoord);\n}',
						initialize: function (t) {
							t && this.setOptions(t);
						},
						setOptions: function (t) {
							for (var e in t) this[e] = t[e];
						},
						createProgram: function (t, e, i) {
							(e = e || this.fragmentSource),
								(i = i || this.vertexSource),
								'highp' !== n.webGlPrecision && (e = e.replace(/precision highp float/g, 'precision ' + n.webGlPrecision + ' float'));
							var r = t.createShader(t.VERTEX_SHADER);
							if ((t.shaderSource(r, i), t.compileShader(r), !t.getShaderParameter(r, t.COMPILE_STATUS)))
								throw new Error('Vertex shader compile error for ' + this.type + ': ' + t.getShaderInfoLog(r));
							var o = t.createShader(t.FRAGMENT_SHADER);
							if ((t.shaderSource(o, e), t.compileShader(o), !t.getShaderParameter(o, t.COMPILE_STATUS)))
								throw new Error('Fragment shader compile error for ' + this.type + ': ' + t.getShaderInfoLog(o));
							var s = t.createProgram();
							if ((t.attachShader(s, r), t.attachShader(s, o), t.linkProgram(s), !t.getProgramParameter(s, t.LINK_STATUS)))
								throw new Error('Shader link error for "${this.type}" ' + t.getProgramInfoLog(s));
							var a = this.getAttributeLocations(t, s),
								c = this.getUniformLocations(t, s) || {};
							return (c.uStepW = t.getUniformLocation(s, 'uStepW')), (c.uStepH = t.getUniformLocation(s, 'uStepH')), { program: s, attributeLocations: a, uniformLocations: c };
						},
						getAttributeLocations: function (t, e) {
							return { aPosition: t.getAttribLocation(e, 'aPosition') };
						},
						getUniformLocations: function () {
							return {};
						},
						sendAttributeData: function (t, e, i) {
							var n = e.aPosition,
								r = t.createBuffer();
							t.bindBuffer(t.ARRAY_BUFFER, r), t.enableVertexAttribArray(n), t.vertexAttribPointer(n, 2, t.FLOAT, !1, 0, 0), t.bufferData(t.ARRAY_BUFFER, i, t.STATIC_DRAW);
						},
						_setupFrameBuffer: function (t) {
							var e,
								i,
								n = t.context;
							t.passes > 1
								? ((e = t.destinationWidth),
								  (i = t.destinationHeight),
								  (t.sourceWidth === e && t.sourceHeight === i) || (n.deleteTexture(t.targetTexture), (t.targetTexture = t.filterBackend.createTexture(n, e, i))),
								  n.framebufferTexture2D(n.FRAMEBUFFER, n.COLOR_ATTACHMENT0, n.TEXTURE_2D, t.targetTexture, 0))
								: (n.bindFramebuffer(n.FRAMEBUFFER, null), n.finish());
						},
						_swapTextures: function (t) {
							t.passes--, t.pass++;
							var e = t.targetTexture;
							(t.targetTexture = t.sourceTexture), (t.sourceTexture = e);
						},
						isNeutralState: function () {
							var t = this.mainParameter,
								e = n.Image.filters[this.type].prototype;
							if (t) {
								if (Array.isArray(e[t])) {
									for (var i = e[t].length; i--; ) if (this[t][i] !== e[t][i]) return !1;
									return !0;
								}
								return e[t] === this[t];
							}
							return !1;
						},
						applyTo: function (t) {
							t.webgl ? (this._setupFrameBuffer(t), this.applyToWebGL(t), this._swapTextures(t)) : this.applyTo2d(t);
						},
						retrieveShader: function (t) {
							return t.programCache.hasOwnProperty(this.type) || (t.programCache[this.type] = this.createProgram(t.context)), t.programCache[this.type];
						},
						applyToWebGL: function (t) {
							var e = t.context,
								i = this.retrieveShader(t);
							0 === t.pass && t.originalTexture ? e.bindTexture(e.TEXTURE_2D, t.originalTexture) : e.bindTexture(e.TEXTURE_2D, t.sourceTexture),
								e.useProgram(i.program),
								this.sendAttributeData(e, i.attributeLocations, t.aPosition),
								e.uniform1f(i.uniformLocations.uStepW, 1 / t.sourceWidth),
								e.uniform1f(i.uniformLocations.uStepH, 1 / t.sourceHeight),
								this.sendUniformData(e, i.uniformLocations),
								e.viewport(0, 0, t.destinationWidth, t.destinationHeight),
								e.drawArrays(e.TRIANGLE_STRIP, 0, 4);
						},
						bindAdditionalTexture: function (t, e, i) {
							t.activeTexture(i), t.bindTexture(t.TEXTURE_2D, e), t.activeTexture(t.TEXTURE0);
						},
						unbindAdditionalTexture: function (t, e) {
							t.activeTexture(e), t.bindTexture(t.TEXTURE_2D, null), t.activeTexture(t.TEXTURE0);
						},
						getMainParameter: function () {
							return this[this.mainParameter];
						},
						setMainParameter: function (t) {
							this[this.mainParameter] = t;
						},
						sendUniformData: function () {},
						createHelpLayer: function (t) {
							if (!t.helpLayer) {
								var e = document.createElement('canvas');
								(e.width = t.sourceWidth), (e.height = t.sourceHeight), (t.helpLayer = e);
							}
						},
						toObject: function () {
							var t = { type: this.type },
								e = this.mainParameter;
							return e && (t[e] = this[e]), t;
						},
						toJSON: function () {
							return this.toObject();
						}
					})),
					(n.Image.filters.BaseFilter.fromObject = function (t, e) {
						var i = new n.Image.filters[t.type](t);
						return e && e(i), i;
					}),
					(function (t) {
						'use strict';
						var e = t.fabric || (t.fabric = {}),
							i = e.Image.filters,
							n = e.util.createClass;
						(i.ColorMatrix = n(i.BaseFilter, {
							type: 'ColorMatrix',
							fragmentSource:
								'precision highp float;\nuniform sampler2D uTexture;\nvarying vec2 vTexCoord;\nuniform mat4 uColorMatrix;\nuniform vec4 uConstants;\nvoid main() {\nvec4 color = texture2D(uTexture, vTexCoord);\ncolor *= uColorMatrix;\ncolor += uConstants;\ngl_FragColor = color;\n}',
							matrix: [1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0],
							mainParameter: 'matrix',
							colorsOnly: !0,
							initialize: function (t) {
								this.callSuper('initialize', t), (this.matrix = this.matrix.slice(0));
							},
							applyTo2d: function (t) {
								var e,
									i,
									n,
									r,
									o,
									s = t.imageData,
									a = s.data,
									c = a.length,
									h = this.matrix,
									l = this.colorsOnly;
								for (o = 0; o < c; o += 4)
									(e = a[o]),
										(i = a[o + 1]),
										(n = a[o + 2]),
										l
											? ((a[o] = e * h[0] + i * h[1] + n * h[2] + 255 * h[4]),
											  (a[o + 1] = e * h[5] + i * h[6] + n * h[7] + 255 * h[9]),
											  (a[o + 2] = e * h[10] + i * h[11] + n * h[12] + 255 * h[14]))
											: ((r = a[o + 3]),
											  (a[o] = e * h[0] + i * h[1] + n * h[2] + r * h[3] + 255 * h[4]),
											  (a[o + 1] = e * h[5] + i * h[6] + n * h[7] + r * h[8] + 255 * h[9]),
											  (a[o + 2] = e * h[10] + i * h[11] + n * h[12] + r * h[13] + 255 * h[14]),
											  (a[o + 3] = e * h[15] + i * h[16] + n * h[17] + r * h[18] + 255 * h[19]));
							},
							getUniformLocations: function (t, e) {
								return { uColorMatrix: t.getUniformLocation(e, 'uColorMatrix'), uConstants: t.getUniformLocation(e, 'uConstants') };
							},
							sendUniformData: function (t, e) {
								var i = this.matrix,
									n = [i[0], i[1], i[2], i[3], i[5], i[6], i[7], i[8], i[10], i[11], i[12], i[13], i[15], i[16], i[17], i[18]],
									r = [i[4], i[9], i[14], i[19]];
								t.uniformMatrix4fv(e.uColorMatrix, !1, n), t.uniform4fv(e.uConstants, r);
							}
						})),
							(e.Image.filters.ColorMatrix.fromObject = e.Image.filters.BaseFilter.fromObject);
					})(e),
					(function (t) {
						'use strict';
						var e = t.fabric || (t.fabric = {}),
							i = e.Image.filters,
							n = e.util.createClass;
						(i.Brightness = n(i.BaseFilter, {
							type: 'Brightness',
							fragmentSource:
								'precision highp float;\nuniform sampler2D uTexture;\nuniform float uBrightness;\nvarying vec2 vTexCoord;\nvoid main() {\nvec4 color = texture2D(uTexture, vTexCoord);\ncolor.rgb += uBrightness;\ngl_FragColor = color;\n}',
							brightness: 0,
							mainParameter: 'brightness',
							applyTo2d: function (t) {
								if (0 !== this.brightness) {
									var e,
										i = t.imageData,
										n = i.data,
										r = n.length,
										o = Math.round(255 * this.brightness);
									for (e = 0; e < r; e += 4) (n[e] = n[e] + o), (n[e + 1] = n[e + 1] + o), (n[e + 2] = n[e + 2] + o);
								}
							},
							getUniformLocations: function (t, e) {
								return { uBrightness: t.getUniformLocation(e, 'uBrightness') };
							},
							sendUniformData: function (t, e) {
								t.uniform1f(e.uBrightness, this.brightness);
							}
						})),
							(e.Image.filters.Brightness.fromObject = e.Image.filters.BaseFilter.fromObject);
					})(e),
					(function (t) {
						'use strict';
						var e = t.fabric || (t.fabric = {}),
							i = e.util.object.extend,
							n = e.Image.filters,
							r = e.util.createClass;
						(n.Convolute = r(n.BaseFilter, {
							type: 'Convolute',
							opaque: !1,
							matrix: [0, 0, 0, 0, 1, 0, 0, 0, 0],
							fragmentSource: {
								Convolute_3_1:
									'precision highp float;\nuniform sampler2D uTexture;\nuniform float uMatrix[9];\nuniform float uStepW;\nuniform float uStepH;\nvarying vec2 vTexCoord;\nvoid main() {\nvec4 color = vec4(0, 0, 0, 0);\nfor (float h = 0.0; h < 3.0; h+=1.0) {\nfor (float w = 0.0; w < 3.0; w+=1.0) {\nvec2 matrixPos = vec2(uStepW * (w - 1), uStepH * (h - 1));\ncolor += texture2D(uTexture, vTexCoord + matrixPos) * uMatrix[int(h * 3.0 + w)];\n}\n}\ngl_FragColor = color;\n}',
								Convolute_3_0:
									'precision highp float;\nuniform sampler2D uTexture;\nuniform float uMatrix[9];\nuniform float uStepW;\nuniform float uStepH;\nvarying vec2 vTexCoord;\nvoid main() {\nvec4 color = vec4(0, 0, 0, 1);\nfor (float h = 0.0; h < 3.0; h+=1.0) {\nfor (float w = 0.0; w < 3.0; w+=1.0) {\nvec2 matrixPos = vec2(uStepW * (w - 1.0), uStepH * (h - 1.0));\ncolor.rgb += texture2D(uTexture, vTexCoord + matrixPos).rgb * uMatrix[int(h * 3.0 + w)];\n}\n}\nfloat alpha = texture2D(uTexture, vTexCoord).a;\ngl_FragColor = color;\ngl_FragColor.a = alpha;\n}',
								Convolute_5_1:
									'precision highp float;\nuniform sampler2D uTexture;\nuniform float uMatrix[25];\nuniform float uStepW;\nuniform float uStepH;\nvarying vec2 vTexCoord;\nvoid main() {\nvec4 color = vec4(0, 0, 0, 0);\nfor (float h = 0.0; h < 5.0; h+=1.0) {\nfor (float w = 0.0; w < 5.0; w+=1.0) {\nvec2 matrixPos = vec2(uStepW * (w - 2.0), uStepH * (h - 2.0));\ncolor += texture2D(uTexture, vTexCoord + matrixPos) * uMatrix[int(h * 5.0 + w)];\n}\n}\ngl_FragColor = color;\n}',
								Convolute_5_0:
									'precision highp float;\nuniform sampler2D uTexture;\nuniform float uMatrix[25];\nuniform float uStepW;\nuniform float uStepH;\nvarying vec2 vTexCoord;\nvoid main() {\nvec4 color = vec4(0, 0, 0, 1);\nfor (float h = 0.0; h < 5.0; h+=1.0) {\nfor (float w = 0.0; w < 5.0; w+=1.0) {\nvec2 matrixPos = vec2(uStepW * (w - 2.0), uStepH * (h - 2.0));\ncolor.rgb += texture2D(uTexture, vTexCoord + matrixPos).rgb * uMatrix[int(h * 5.0 + w)];\n}\n}\nfloat alpha = texture2D(uTexture, vTexCoord).a;\ngl_FragColor = color;\ngl_FragColor.a = alpha;\n}',
								Convolute_7_1:
									'precision highp float;\nuniform sampler2D uTexture;\nuniform float uMatrix[49];\nuniform float uStepW;\nuniform float uStepH;\nvarying vec2 vTexCoord;\nvoid main() {\nvec4 color = vec4(0, 0, 0, 0);\nfor (float h = 0.0; h < 7.0; h+=1.0) {\nfor (float w = 0.0; w < 7.0; w+=1.0) {\nvec2 matrixPos = vec2(uStepW * (w - 3.0), uStepH * (h - 3.0));\ncolor += texture2D(uTexture, vTexCoord + matrixPos) * uMatrix[int(h * 7.0 + w)];\n}\n}\ngl_FragColor = color;\n}',
								Convolute_7_0:
									'precision highp float;\nuniform sampler2D uTexture;\nuniform float uMatrix[49];\nuniform float uStepW;\nuniform float uStepH;\nvarying vec2 vTexCoord;\nvoid main() {\nvec4 color = vec4(0, 0, 0, 1);\nfor (float h = 0.0; h < 7.0; h+=1.0) {\nfor (float w = 0.0; w < 7.0; w+=1.0) {\nvec2 matrixPos = vec2(uStepW * (w - 3.0), uStepH * (h - 3.0));\ncolor.rgb += texture2D(uTexture, vTexCoord + matrixPos).rgb * uMatrix[int(h * 7.0 + w)];\n}\n}\nfloat alpha = texture2D(uTexture, vTexCoord).a;\ngl_FragColor = color;\ngl_FragColor.a = alpha;\n}',
								Convolute_9_1:
									'precision highp float;\nuniform sampler2D uTexture;\nuniform float uMatrix[81];\nuniform float uStepW;\nuniform float uStepH;\nvarying vec2 vTexCoord;\nvoid main() {\nvec4 color = vec4(0, 0, 0, 0);\nfor (float h = 0.0; h < 9.0; h+=1.0) {\nfor (float w = 0.0; w < 9.0; w+=1.0) {\nvec2 matrixPos = vec2(uStepW * (w - 4.0), uStepH * (h - 4.0));\ncolor += texture2D(uTexture, vTexCoord + matrixPos) * uMatrix[int(h * 9.0 + w)];\n}\n}\ngl_FragColor = color;\n}',
								Convolute_9_0:
									'precision highp float;\nuniform sampler2D uTexture;\nuniform float uMatrix[81];\nuniform float uStepW;\nuniform float uStepH;\nvarying vec2 vTexCoord;\nvoid main() {\nvec4 color = vec4(0, 0, 0, 1);\nfor (float h = 0.0; h < 9.0; h+=1.0) {\nfor (float w = 0.0; w < 9.0; w+=1.0) {\nvec2 matrixPos = vec2(uStepW * (w - 4.0), uStepH * (h - 4.0));\ncolor.rgb += texture2D(uTexture, vTexCoord + matrixPos).rgb * uMatrix[int(h * 9.0 + w)];\n}\n}\nfloat alpha = texture2D(uTexture, vTexCoord).a;\ngl_FragColor = color;\ngl_FragColor.a = alpha;\n}'
							},
							retrieveShader: function (t) {
								var e = Math.sqrt(this.matrix.length),
									i = this.type + '_' + e + '_' + (this.opaque ? 1 : 0),
									n = this.fragmentSource[i];
								return t.programCache.hasOwnProperty(i) || (t.programCache[i] = this.createProgram(t.context, n)), t.programCache[i];
							},
							applyTo2d: function (t) {
								var e,
									i,
									n,
									r,
									o,
									s,
									a,
									c,
									h,
									l,
									u,
									f,
									d,
									p = t.imageData,
									g = p.data,
									v = this.matrix,
									m = Math.round(Math.sqrt(v.length)),
									y = Math.floor(m / 2),
									b = p.width,
									x = p.height,
									_ = t.ctx.createImageData(b, x),
									w = _.data,
									C = this.opaque ? 1 : 0;
								for (u = 0; u < x; u++)
									for (l = 0; l < b; l++) {
										for (o = 4 * (u * b + l), e = 0, i = 0, n = 0, r = 0, d = 0; d < m; d++)
											for (f = 0; f < m; f++)
												(a = u + d - y),
													(s = l + f - y),
													a < 0 ||
														a >= x ||
														s < 0 ||
														s >= b ||
														((c = 4 * (a * b + s)), (h = v[d * m + f]), (e += g[c] * h), (i += g[c + 1] * h), (n += g[c + 2] * h), C || (r += g[c + 3] * h));
										(w[o] = e), (w[o + 1] = i), (w[o + 2] = n), (w[o + 3] = C ? g[o + 3] : r);
									}
								t.imageData = _;
							},
							getUniformLocations: function (t, e) {
								return {
									uMatrix: t.getUniformLocation(e, 'uMatrix'),
									uOpaque: t.getUniformLocation(e, 'uOpaque'),
									uHalfSize: t.getUniformLocation(e, 'uHalfSize'),
									uSize: t.getUniformLocation(e, 'uSize')
								};
							},
							sendUniformData: function (t, e) {
								t.uniform1fv(e.uMatrix, this.matrix);
							},
							toObject: function () {
								return i(this.callSuper('toObject'), { opaque: this.opaque, matrix: this.matrix });
							}
						})),
							(e.Image.filters.Convolute.fromObject = e.Image.filters.BaseFilter.fromObject);
					})(e),
					(function (t) {
						'use strict';
						var e = t.fabric || (t.fabric = {}),
							i = e.Image.filters,
							n = e.util.createClass;
						(i.Grayscale = n(i.BaseFilter, {
							type: 'Grayscale',
							fragmentSource: {
								average:
									'precision highp float;\nuniform sampler2D uTexture;\nvarying vec2 vTexCoord;\nvoid main() {\nvec4 color = texture2D(uTexture, vTexCoord);\nfloat average = (color.r + color.b + color.g) / 3.0;\ngl_FragColor = vec4(average, average, average, color.a);\n}',
								lightness:
									'precision highp float;\nuniform sampler2D uTexture;\nuniform int uMode;\nvarying vec2 vTexCoord;\nvoid main() {\nvec4 col = texture2D(uTexture, vTexCoord);\nfloat average = (max(max(col.r, col.g),col.b) + min(min(col.r, col.g),col.b)) / 2.0;\ngl_FragColor = vec4(average, average, average, col.a);\n}',
								luminosity:
									'precision highp float;\nuniform sampler2D uTexture;\nuniform int uMode;\nvarying vec2 vTexCoord;\nvoid main() {\nvec4 col = texture2D(uTexture, vTexCoord);\nfloat average = 0.21 * col.r + 0.72 * col.g + 0.07 * col.b;\ngl_FragColor = vec4(average, average, average, col.a);\n}'
							},
							mode: 'average',
							mainParameter: 'mode',
							applyTo2d: function (t) {
								var e,
									i,
									n = t.imageData,
									r = n.data,
									o = r.length,
									s = this.mode;
								for (e = 0; e < o; e += 4)
									'average' === s
										? (i = (r[e] + r[e + 1] + r[e + 2]) / 3)
										: 'lightness' === s
										? (i = (Math.min(r[e], r[e + 1], r[e + 2]) + Math.max(r[e], r[e + 1], r[e + 2])) / 2)
										: 'luminosity' === s && (i = 0.21 * r[e] + 0.72 * r[e + 1] + 0.07 * r[e + 2]),
										(r[e] = i),
										(r[e + 1] = i),
										(r[e + 2] = i);
							},
							retrieveShader: function (t) {
								var e = this.type + '_' + this.mode;
								if (!t.programCache.hasOwnProperty(e)) {
									var i = this.fragmentSource[this.mode];
									t.programCache[e] = this.createProgram(t.context, i);
								}
								return t.programCache[e];
							},
							getUniformLocations: function (t, e) {
								return { uMode: t.getUniformLocation(e, 'uMode') };
							},
							sendUniformData: function (t, e) {
								var i = 1;
								t.uniform1i(e.uMode, i);
							},
							isNeutralState: function () {
								return !1;
							}
						})),
							(e.Image.filters.Grayscale.fromObject = e.Image.filters.BaseFilter.fromObject);
					})(e),
					(function (t) {
						'use strict';
						var e = t.fabric || (t.fabric = {}),
							i = e.Image.filters,
							n = e.util.createClass;
						(i.Invert = n(i.BaseFilter, {
							type: 'Invert',
							fragmentSource:
								'precision highp float;\nuniform sampler2D uTexture;\nuniform int uInvert;\nvarying vec2 vTexCoord;\nvoid main() {\nvec4 color = texture2D(uTexture, vTexCoord);\nif (uInvert == 1) {\ngl_FragColor = vec4(1.0 - color.r,1.0 -color.g,1.0 -color.b,color.a);\n} else {\ngl_FragColor = color;\n}\n}',
							invert: !0,
							mainParameter: 'invert',
							applyTo2d: function (t) {
								var e,
									i = t.imageData,
									n = i.data,
									r = n.length;
								for (e = 0; e < r; e += 4) (n[e] = 255 - n[e]), (n[e + 1] = 255 - n[e + 1]), (n[e + 2] = 255 - n[e + 2]);
							},
							isNeutralState: function () {
								return !this.invert;
							},
							getUniformLocations: function (t, e) {
								return { uInvert: t.getUniformLocation(e, 'uInvert') };
							},
							sendUniformData: function (t, e) {
								t.uniform1i(e.uInvert, this.invert);
							}
						})),
							(e.Image.filters.Invert.fromObject = e.Image.filters.BaseFilter.fromObject);
					})(e),
					(function (t) {
						'use strict';
						var e = t.fabric || (t.fabric = {}),
							i = e.util.object.extend,
							n = e.Image.filters,
							r = e.util.createClass;
						(n.Noise = r(n.BaseFilter, {
							type: 'Noise',
							fragmentSource:
								'precision highp float;\nuniform sampler2D uTexture;\nuniform float uStepH;\nuniform float uNoise;\nuniform float uSeed;\nvarying vec2 vTexCoord;\nfloat rand(vec2 co, float seed, float vScale) {\nreturn fract(sin(dot(co.xy * vScale ,vec2(12.9898 , 78.233))) * 43758.5453 * (seed + 0.01) / 2.0);\n}\nvoid main() {\nvec4 color = texture2D(uTexture, vTexCoord);\ncolor.rgb += (0.5 - rand(vTexCoord, uSeed, 0.1 / uStepH)) * uNoise;\ngl_FragColor = color;\n}',
							mainParameter: 'noise',
							noise: 0,
							applyTo2d: function (t) {
								if (0 !== this.noise) {
									var e,
										i,
										n = t.imageData,
										r = n.data,
										o = r.length,
										s = this.noise;
									for (e = 0, o = r.length; e < o; e += 4) (i = (0.5 - Math.random()) * s), (r[e] += i), (r[e + 1] += i), (r[e + 2] += i);
								}
							},
							getUniformLocations: function (t, e) {
								return { uNoise: t.getUniformLocation(e, 'uNoise'), uSeed: t.getUniformLocation(e, 'uSeed') };
							},
							sendUniformData: function (t, e) {
								t.uniform1f(e.uNoise, this.noise / 255), t.uniform1f(e.uSeed, Math.random());
							},
							toObject: function () {
								return i(this.callSuper('toObject'), { noise: this.noise });
							}
						})),
							(e.Image.filters.Noise.fromObject = e.Image.filters.BaseFilter.fromObject);
					})(e),
					(function (t) {
						'use strict';
						var e = t.fabric || (t.fabric = {}),
							i = e.Image.filters,
							n = e.util.createClass;
						(i.Pixelate = n(i.BaseFilter, {
							type: 'Pixelate',
							blocksize: 4,
							mainParameter: 'blocksize',
							fragmentSource:
								'precision highp float;\nuniform sampler2D uTexture;\nuniform float uBlocksize;\nuniform float uStepW;\nuniform float uStepH;\nvarying vec2 vTexCoord;\nvoid main() {\nfloat blockW = uBlocksize * uStepW;\nfloat blockH = uBlocksize * uStepW;\nint posX = int(vTexCoord.x / blockW);\nint posY = int(vTexCoord.y / blockH);\nfloat fposX = float(posX);\nfloat fposY = float(posY);\nvec2 squareCoords = vec2(fposX * blockW, fposY * blockH);\nvec4 color = texture2D(uTexture, squareCoords);\ngl_FragColor = color;\n}',
							applyTo2d: function (t) {
								var e,
									i,
									n,
									r,
									o,
									s,
									a,
									c,
									h,
									l,
									u,
									f = t.imageData,
									d = f.data,
									p = f.height,
									g = f.width;
								for (i = 0; i < p; i += this.blocksize)
									for (n = 0; n < g; n += this.blocksize)
										for (
											e = 4 * i * g + 4 * n, r = d[e], o = d[e + 1], s = d[e + 2], a = d[e + 3], l = Math.min(i + this.blocksize, p), u = Math.min(n + this.blocksize, g), c = i;
											c < l;
											c++
										)
											for (h = n; h < u; h++) (e = 4 * c * g + 4 * h), (d[e] = r), (d[e + 1] = o), (d[e + 2] = s), (d[e + 3] = a);
							},
							isNeutralState: function () {
								return 1 === this.blocksize;
							},
							getUniformLocations: function (t, e) {
								return { uBlocksize: t.getUniformLocation(e, 'uBlocksize'), uStepW: t.getUniformLocation(e, 'uStepW'), uStepH: t.getUniformLocation(e, 'uStepH') };
							},
							sendUniformData: function (t, e) {
								t.uniform1f(e.uBlocksize, this.blocksize);
							}
						})),
							(e.Image.filters.Pixelate.fromObject = e.Image.filters.BaseFilter.fromObject);
					})(e),
					(function (t) {
						'use strict';
						var e = t.fabric || (t.fabric = {}),
							i = e.util.object.extend,
							n = e.Image.filters,
							r = e.util.createClass;
						(n.RemoveColor = r(n.BaseFilter, {
							type: 'RemoveColor',
							color: '#FFFFFF',
							fragmentSource:
								'precision highp float;\nuniform sampler2D uTexture;\nuniform vec4 uLow;\nuniform vec4 uHigh;\nvarying vec2 vTexCoord;\nvoid main() {\ngl_FragColor = texture2D(uTexture, vTexCoord);\nif(all(greaterThan(gl_FragColor.rgb,uLow.rgb)) && all(greaterThan(uHigh.rgb,gl_FragColor.rgb))) {\ngl_FragColor.a = 0.0;\n}\n}',
							distance: 0.02,
							useAlpha: !1,
							applyTo2d: function (t) {
								var i,
									n,
									r,
									o,
									s = t.imageData,
									a = s.data,
									c = 255 * this.distance,
									h = new e.Color(this.color).getSource(),
									l = [h[0] - c, h[1] - c, h[2] - c],
									u = [h[0] + c, h[1] + c, h[2] + c];
								for (i = 0; i < a.length; i += 4) (n = a[i]), (r = a[i + 1]), (o = a[i + 2]), n > l[0] && r > l[1] && o > l[2] && n < u[0] && r < u[1] && o < u[2] && (a[i + 3] = 0);
							},
							getUniformLocations: function (t, e) {
								return { uLow: t.getUniformLocation(e, 'uLow'), uHigh: t.getUniformLocation(e, 'uHigh') };
							},
							sendUniformData: function (t, i) {
								var n = new e.Color(this.color).getSource(),
									r = parseFloat(this.distance),
									o = [0 + n[0] / 255 - r, 0 + n[1] / 255 - r, 0 + n[2] / 255 - r, 1],
									s = [n[0] / 255 + r, n[1] / 255 + r, n[2] / 255 + r, 1];
								t.uniform4fv(i.uLow, o), t.uniform4fv(i.uHigh, s);
							},
							toObject: function () {
								return i(this.callSuper('toObject'), { color: this.color, distance: this.distance });
							}
						})),
							(e.Image.filters.RemoveColor.fromObject = e.Image.filters.BaseFilter.fromObject);
					})(e),
					(function (t) {
						'use strict';
						var e = t.fabric || (t.fabric = {}),
							i = e.Image.filters,
							n = e.util.createClass,
							r = {
								Brownie: [0.5997, 0.34553, -0.27082, 0, 0.186, -0.0377, 0.86095, 0.15059, 0, -0.1449, 0.24113, -0.07441, 0.44972, 0, -0.02965, 0, 0, 0, 1, 0],
								Vintage: [0.62793, 0.32021, -0.03965, 0, 0.03784, 0.02578, 0.64411, 0.03259, 0, 0.02926, 0.0466, -0.08512, 0.52416, 0, 0.02023, 0, 0, 0, 1, 0],
								Kodachrome: [1.12855, -0.39673, -0.03992, 0, 0.24991, -0.16404, 1.08352, -0.05498, 0, 0.09698, -0.16786, -0.56034, 1.60148, 0, 0.13972, 0, 0, 0, 1, 0],
								Technicolor: [1.91252, -0.85453, -0.09155, 0, 0.04624, -0.30878, 1.76589, -0.10601, 0, -0.27589, -0.2311, -0.75018, 1.84759, 0, 0.12137, 0, 0, 0, 1, 0],
								Polaroid: [1.438, -0.062, -0.062, 0, 0, -0.122, 1.378, -0.122, 0, 0, -0.016, -0.016, 1.483, 0, 0, 0, 0, 0, 1, 0],
								Sepia: [0.393, 0.769, 0.189, 0, 0, 0.349, 0.686, 0.168, 0, 0, 0.272, 0.534, 0.131, 0, 0, 0, 0, 0, 1, 0],
								BlackWhite: [1.5, 1.5, 1.5, 0, -1, 1.5, 1.5, 1.5, 0, -1, 1.5, 1.5, 1.5, 0, -1, 0, 0, 0, 1, 0]
							};
						for (var o in r)
							(i[o] = n(i.ColorMatrix, { type: o, matrix: r[o], mainParameter: !1, colorsOnly: !0 })), (e.Image.filters[o].fromObject = e.Image.filters.BaseFilter.fromObject);
					})(e),
					(function (t) {
						'use strict';
						var e = t.fabric,
							i = e.Image.filters,
							n = e.util.createClass;
						(i.BlendColor = n(i.BaseFilter, {
							type: 'BlendColor',
							color: '#F95C63',
							mode: 'multiply',
							alpha: 1,
							fragmentSource: {
								multiply: 'gl_FragColor.rgb *= uColor.rgb;\n',
								screen: 'gl_FragColor.rgb = 1.0 - (1.0 - gl_FragColor.rgb) * (1.0 - uColor.rgb);\n',
								add: 'gl_FragColor.rgb += uColor.rgb;\n',
								diff: 'gl_FragColor.rgb = abs(gl_FragColor.rgb - uColor.rgb);\n',
								subtract: 'gl_FragColor.rgb -= uColor.rgb;\n',
								lighten: 'gl_FragColor.rgb = max(gl_FragColor.rgb, uColor.rgb);\n',
								darken: 'gl_FragColor.rgb = min(gl_FragColor.rgb, uColor.rgb);\n',
								exclusion: 'gl_FragColor.rgb += uColor.rgb - 2.0 * (uColor.rgb * gl_FragColor.rgb);\n',
								overlay:
									'if (uColor.r < 0.5) {\ngl_FragColor.r *= 2.0 * uColor.r;\n} else {\ngl_FragColor.r = 1.0 - 2.0 * (1.0 - gl_FragColor.r) * (1.0 - uColor.r);\n}\nif (uColor.g < 0.5) {\ngl_FragColor.g *= 2.0 * uColor.g;\n} else {\ngl_FragColor.g = 1.0 - 2.0 * (1.0 - gl_FragColor.g) * (1.0 - uColor.g);\n}\nif (uColor.b < 0.5) {\ngl_FragColor.b *= 2.0 * uColor.b;\n} else {\ngl_FragColor.b = 1.0 - 2.0 * (1.0 - gl_FragColor.b) * (1.0 - uColor.b);\n}\n',
								tint: 'gl_FragColor.rgb *= (1.0 - uColor.a);\ngl_FragColor.rgb += uColor.rgb;\n'
							},
							buildSource: function (t) {
								return (
									'precision highp float;\nuniform sampler2D uTexture;\nuniform vec4 uColor;\nvarying vec2 vTexCoord;\nvoid main() {\nvec4 color = texture2D(uTexture, vTexCoord);\ngl_FragColor = color;\nif (color.a > 0.0) {\n' +
									this.fragmentSource[t] +
									'}\n}'
								);
							},
							retrieveShader: function (t) {
								var e,
									i = this.type + '_' + this.mode;
								return t.programCache.hasOwnProperty(i) || ((e = this.buildSource(this.mode)), (t.programCache[i] = this.createProgram(t.context, e))), t.programCache[i];
							},
							applyTo2d: function (t) {
								var i,
									n,
									r,
									o,
									s,
									a,
									c,
									h = t.imageData,
									l = h.data,
									u = l.length,
									f = 1 - this.alpha;
								(c = new e.Color(this.color).getSource()), (i = c[0] * this.alpha), (n = c[1] * this.alpha), (r = c[2] * this.alpha);
								for (var d = 0; d < u; d += 4)
									switch (((o = l[d]), (s = l[d + 1]), (a = l[d + 2]), this.mode)) {
										case 'multiply':
											(l[d] = (o * i) / 255), (l[d + 1] = (s * n) / 255), (l[d + 2] = (a * r) / 255);
											break;
										case 'screen':
											(l[d] = 255 - ((255 - o) * (255 - i)) / 255), (l[d + 1] = 255 - ((255 - s) * (255 - n)) / 255), (l[d + 2] = 255 - ((255 - a) * (255 - r)) / 255);
											break;
										case 'add':
											(l[d] = o + i), (l[d + 1] = s + n), (l[d + 2] = a + r);
											break;
										case 'diff':
										case 'difference':
											(l[d] = Math.abs(o - i)), (l[d + 1] = Math.abs(s - n)), (l[d + 2] = Math.abs(a - r));
											break;
										case 'subtract':
											(l[d] = o - i), (l[d + 1] = s - n), (l[d + 2] = a - r);
											break;
										case 'darken':
											(l[d] = Math.min(o, i)), (l[d + 1] = Math.min(s, n)), (l[d + 2] = Math.min(a, r));
											break;
										case 'lighten':
											(l[d] = Math.max(o, i)), (l[d + 1] = Math.max(s, n)), (l[d + 2] = Math.max(a, r));
											break;
										case 'overlay':
											(l[d] = i < 128 ? (2 * o * i) / 255 : 255 - (2 * (255 - o) * (255 - i)) / 255),
												(l[d + 1] = n < 128 ? (2 * s * n) / 255 : 255 - (2 * (255 - s) * (255 - n)) / 255),
												(l[d + 2] = r < 128 ? (2 * a * r) / 255 : 255 - (2 * (255 - a) * (255 - r)) / 255);
											break;
										case 'exclusion':
											(l[d] = i + o - (2 * i * o) / 255), (l[d + 1] = n + s - (2 * n * s) / 255), (l[d + 2] = r + a - (2 * r * a) / 255);
											break;
										case 'tint':
											(l[d] = i + o * f), (l[d + 1] = n + s * f), (l[d + 2] = r + a * f);
									}
							},
							getUniformLocations: function (t, e) {
								return { uColor: t.getUniformLocation(e, 'uColor') };
							},
							sendUniformData: function (t, i) {
								var n = new e.Color(this.color).getSource();
								(n[0] = (this.alpha * n[0]) / 255), (n[1] = (this.alpha * n[1]) / 255), (n[2] = (this.alpha * n[2]) / 255), (n[3] = this.alpha), t.uniform4fv(i.uColor, n);
							},
							toObject: function () {
								return { type: this.type, color: this.color, mode: this.mode, alpha: this.alpha };
							}
						})),
							(e.Image.filters.BlendColor.fromObject = e.Image.filters.BaseFilter.fromObject);
					})(e),
					(function (t) {
						'use strict';
						var e = t.fabric,
							i = e.Image.filters,
							n = e.util.createClass;
						(i.BlendImage = n(i.BaseFilter, {
							type: 'BlendImage',
							image: null,
							mode: 'multiply',
							alpha: 1,
							vertexSource:
								'attribute vec2 aPosition;\nvarying vec2 vTexCoord;\nvarying vec2 vTexCoord2;\nuniform mat3 uTransformMatrix;\nvoid main() {\nvTexCoord = aPosition;\nvTexCoord2 = (uTransformMatrix * vec3(aPosition, 1.0)).xy;\ngl_Position = vec4(aPosition * 2.0 - 1.0, 0.0, 1.0);\n}',
							fragmentSource: {
								multiply:
									'precision highp float;\nuniform sampler2D uTexture;\nuniform sampler2D uImage;\nuniform vec4 uColor;\nvarying vec2 vTexCoord;\nvarying vec2 vTexCoord2;\nvoid main() {\nvec4 color = texture2D(uTexture, vTexCoord);\nvec4 color2 = texture2D(uImage, vTexCoord2);\ncolor.rgba *= color2.rgba;\ngl_FragColor = color;\n}',
								mask: 'precision highp float;\nuniform sampler2D uTexture;\nuniform sampler2D uImage;\nuniform vec4 uColor;\nvarying vec2 vTexCoord;\nvarying vec2 vTexCoord2;\nvoid main() {\nvec4 color = texture2D(uTexture, vTexCoord);\nvec4 color2 = texture2D(uImage, vTexCoord2);\ncolor.a = color2.a;\ngl_FragColor = color;\n}'
							},
							retrieveShader: function (t) {
								var e = this.type + '_' + this.mode,
									i = this.fragmentSource[this.mode];
								return t.programCache.hasOwnProperty(e) || (t.programCache[e] = this.createProgram(t.context, i)), t.programCache[e];
							},
							applyToWebGL: function (t) {
								var e = t.context,
									i = this.createTexture(t.filterBackend, this.image);
								this.bindAdditionalTexture(e, i, e.TEXTURE1), this.callSuper('applyToWebGL', t), this.unbindAdditionalTexture(e, e.TEXTURE1);
							},
							createTexture: function (t, e) {
								return t.getCachedTexture(e.cacheKey, e._element);
							},
							calculateMatrix: function () {
								var t = this.image,
									e = t._element.width,
									i = t._element.height;
								return [1 / t.scaleX, 0, 0, 0, 1 / t.scaleY, 0, -t.left / e, -t.top / i, 1];
							},
							applyTo2d: function (t) {
								var i,
									n,
									r,
									o,
									s,
									a,
									c,
									h,
									l,
									u,
									f,
									d = t.imageData,
									p = t.filterBackend.resources,
									g = d.data,
									v = g.length,
									m = d.width,
									y = d.height,
									b = this.image;
								p.blendImage || (p.blendImage = e.util.createCanvasElement()),
									(l = p.blendImage),
									(u = l.getContext('2d')),
									l.width !== m || l.height !== y ? ((l.width = m), (l.height = y)) : u.clearRect(0, 0, m, y),
									u.setTransform(b.scaleX, 0, 0, b.scaleY, b.left, b.top),
									u.drawImage(b._element, 0, 0, m, y),
									(f = u.getImageData(0, 0, m, y).data);
								for (var x = 0; x < v; x += 4)
									switch (((s = g[x]), (a = g[x + 1]), (c = g[x + 2]), (h = g[x + 3]), (i = f[x]), (n = f[x + 1]), (r = f[x + 2]), (o = f[x + 3]), this.mode)) {
										case 'multiply':
											(g[x] = (s * i) / 255), (g[x + 1] = (a * n) / 255), (g[x + 2] = (c * r) / 255), (g[x + 3] = (h * o) / 255);
											break;
										case 'mask':
											g[x + 3] = o;
											break;
									}
							},
							getUniformLocations: function (t, e) {
								return { uTransformMatrix: t.getUniformLocation(e, 'uTransformMatrix'), uImage: t.getUniformLocation(e, 'uImage') };
							},
							sendUniformData: function (t, e) {
								var i = this.calculateMatrix();
								t.uniform1i(e.uImage, 1), t.uniformMatrix3fv(e.uTransformMatrix, !1, i);
							},
							toObject: function () {
								return { type: this.type, image: this.image && this.image.toObject(), mode: this.mode, alpha: this.alpha };
							}
						})),
							(e.Image.filters.BlendImage.fromObject = function (t, i) {
								e.Image.fromObject(t.image, function (n) {
									var r = e.util.object.clone(t);
									(r.image = n), i(new e.Image.filters.BlendImage(r));
								});
							});
					})(e),
					(function (t) {
						'use strict';
						var e = t.fabric || (t.fabric = {}),
							i = Math.pow,
							n = Math.floor,
							r = Math.sqrt,
							o = Math.abs,
							s = Math.round,
							a = Math.sin,
							c = Math.ceil,
							h = e.Image.filters,
							l = e.util.createClass;
						(h.Resize = l(h.BaseFilter, {
							type: 'Resize',
							resizeType: 'hermite',
							scaleX: 1,
							scaleY: 1,
							lanczosLobes: 3,
							getUniformLocations: function (t, e) {
								return { uDelta: t.getUniformLocation(e, 'uDelta'), uTaps: t.getUniformLocation(e, 'uTaps') };
							},
							sendUniformData: function (t, e) {
								t.uniform2fv(e.uDelta, this.horizontal ? [1 / this.width, 0] : [0, 1 / this.height]), t.uniform1fv(e.uTaps, this.taps);
							},
							retrieveShader: function (t) {
								var e = this.getFilterWindow(),
									i = this.type + '_' + e;
								if (!t.programCache.hasOwnProperty(i)) {
									var n = this.generateShader(e);
									t.programCache[i] = this.createProgram(t.context, n);
								}
								return t.programCache[i];
							},
							getFilterWindow: function () {
								var t = this.tempScale;
								return Math.ceil(this.lanczosLobes / t);
							},
							getTaps: function () {
								for (var t = this.lanczosCreate(this.lanczosLobes), e = this.tempScale, i = this.getFilterWindow(), n = new Array(i), r = 1; r <= i; r++) n[r - 1] = t(r * e);
								return n;
							},
							generateShader: function (t) {
								for (var e = new Array(t), i = this.fragmentSourceTOP, n = 1; n <= t; n++) e[n - 1] = n + '.0 * uDelta';
								return (
									(i += 'uniform float uTaps[' + t + '];\n'),
									(i += 'void main() {\n'),
									(i += '  vec4 color = texture2D(uTexture, vTexCoord);\n'),
									(i += '  float sum = 1.0;\n'),
									e.forEach(function (t, e) {
										(i += '  color += texture2D(uTexture, vTexCoord + ' + t + ') * uTaps[' + e + '];\n'),
											(i += '  color += texture2D(uTexture, vTexCoord - ' + t + ') * uTaps[' + e + '];\n'),
											(i += '  sum += 2.0 * uTaps[' + e + '];\n');
									}),
									(i += '  gl_FragColor = color / sum;\n'),
									(i += '}'),
									i
								);
							},
							fragmentSourceTOP: 'precision highp float;\nuniform sampler2D uTexture;\nuniform vec2 uDelta;\nvarying vec2 vTexCoord;\n',
							applyTo: function (t) {
								t.webgl
									? (t.passes++,
									  (this.width = t.sourceWidth),
									  (this.horizontal = !0),
									  (this.dW = Math.round(this.width * this.scaleX)),
									  (this.dH = t.sourceHeight),
									  (this.tempScale = this.dW / this.width),
									  (this.taps = this.getTaps()),
									  (t.destinationWidth = this.dW),
									  this._setupFrameBuffer(t),
									  this.applyToWebGL(t),
									  this._swapTextures(t),
									  (t.sourceWidth = t.destinationWidth),
									  (this.height = t.sourceHeight),
									  (this.horizontal = !1),
									  (this.dH = Math.round(this.height * this.scaleY)),
									  (this.tempScale = this.dH / this.height),
									  (this.taps = this.getTaps()),
									  (t.destinationHeight = this.dH),
									  this._setupFrameBuffer(t),
									  this.applyToWebGL(t),
									  this._swapTextures(t),
									  (t.sourceHeight = t.destinationHeight))
									: this.applyTo2d(t);
							},
							isNeutralState: function () {
								return 1 === this.scaleX && 1 === this.scaleY;
							},
							lanczosCreate: function (t) {
								return function (e) {
									if (e >= t || e <= -t) return 0;
									if (e < 1.1920929e-7 && e > -1.1920929e-7) return 1;
									e *= Math.PI;
									var i = e / t;
									return ((a(e) / e) * a(i)) / i;
								};
							},
							applyTo2d: function (t) {
								var e = t.imageData,
									i = this.scaleX,
									n = this.scaleY;
								(this.rcpScaleX = 1 / i), (this.rcpScaleY = 1 / n);
								var r,
									o = e.width,
									a = e.height,
									c = s(o * i),
									h = s(a * n);
								'sliceHack' === this.resizeType
									? (r = this.sliceByTwo(t, o, a, c, h))
									: 'hermite' === this.resizeType
									? (r = this.hermiteFastResize(t, o, a, c, h))
									: 'bilinear' === this.resizeType
									? (r = this.bilinearFiltering(t, o, a, c, h))
									: 'lanczos' === this.resizeType && (r = this.lanczosResize(t, o, a, c, h)),
									(t.imageData = r);
							},
							sliceByTwo: function (t, i, r, o, s) {
								var a,
									c,
									h = t.imageData,
									l = 0.5,
									u = !1,
									f = !1,
									d = i * l,
									p = r * l,
									g = e.filterBackend.resources,
									v = 0,
									m = 0,
									y = i,
									b = 0;
								g.sliceByTwo || (g.sliceByTwo = document.createElement('canvas')),
									(a = g.sliceByTwo),
									(a.width < 1.5 * i || a.height < r) && ((a.width = 1.5 * i), (a.height = r)),
									(c = a.getContext('2d')),
									c.clearRect(0, 0, 1.5 * i, r),
									c.putImageData(h, 0, 0),
									(o = n(o)),
									(s = n(s));
								while (!u || !f)
									(i = d),
										(r = p),
										o < n(d * l) ? (d = n(d * l)) : ((d = o), (u = !0)),
										s < n(p * l) ? (p = n(p * l)) : ((p = s), (f = !0)),
										c.drawImage(a, v, m, i, r, y, b, d, p),
										(v = y),
										(m = b),
										(b += p);
								return c.getImageData(v, m, o, s);
							},
							lanczosResize: function (t, e, s, a, h) {
								function l(t) {
									var c, S, T, O, k, P, E, M, j, D, A;
									for (w.x = (t + 0.5) * g, C.x = n(w.x), c = 0; c < h; c++) {
										for (w.y = (c + 0.5) * v, C.y = n(w.y), k = 0, P = 0, E = 0, M = 0, j = 0, S = C.x - b; S <= C.x + b; S++)
											if (!(S < 0 || S >= e)) {
												(D = n(1e3 * o(S - w.x))), _[D] || (_[D] = {});
												for (var F = C.y - x; F <= C.y + x; F++)
													F < 0 ||
														F >= s ||
														((A = n(1e3 * o(F - w.y))),
														_[D][A] || (_[D][A] = p(r(i(D * m, 2) + i(A * y, 2)) / 1e3)),
														(T = _[D][A]),
														T > 0 && ((O = 4 * (F * e + S)), (k += T), (P += T * u[O]), (E += T * u[O + 1]), (M += T * u[O + 2]), (j += T * u[O + 3])));
											}
										(O = 4 * (c * a + t)), (d[O] = P / k), (d[O + 1] = E / k), (d[O + 2] = M / k), (d[O + 3] = j / k);
									}
									return ++t < a ? l(t) : f;
								}
								var u = t.imageData.data,
									f = t.ctx.createImageData(a, h),
									d = f.data,
									p = this.lanczosCreate(this.lanczosLobes),
									g = this.rcpScaleX,
									v = this.rcpScaleY,
									m = 2 / this.rcpScaleX,
									y = 2 / this.rcpScaleY,
									b = c((g * this.lanczosLobes) / 2),
									x = c((v * this.lanczosLobes) / 2),
									_ = {},
									w = {},
									C = {};
								return l(0);
							},
							bilinearFiltering: function (t, e, i, r, o) {
								var s,
									a,
									c,
									h,
									l,
									u,
									f,
									d,
									p,
									g,
									v,
									m,
									y,
									b = 0,
									x = this.rcpScaleX,
									_ = this.rcpScaleY,
									w = 4 * (e - 1),
									C = t.imageData,
									S = C.data,
									T = t.ctx.createImageData(r, o),
									O = T.data;
								for (f = 0; f < o; f++)
									for (d = 0; d < r; d++)
										for (l = n(x * d), u = n(_ * f), p = x * d - l, g = _ * f - u, y = 4 * (u * e + l), v = 0; v < 4; v++)
											(s = S[y + v]),
												(a = S[y + 4 + v]),
												(c = S[y + w + v]),
												(h = S[y + w + 4 + v]),
												(m = s * (1 - p) * (1 - g) + a * p * (1 - g) + c * g * (1 - p) + h * p * g),
												(O[b++] = m);
								return T;
							},
							hermiteFastResize: function (t, e, i, s, a) {
								for (
									var h = this.rcpScaleX, l = this.rcpScaleY, u = c(h / 2), f = c(l / 2), d = t.imageData, p = d.data, g = t.ctx.createImageData(s, a), v = g.data, m = 0;
									m < a;
									m++
								)
									for (var y = 0; y < s; y++) {
										for (var b = 4 * (y + m * s), x = 0, _ = 0, w = 0, C = 0, S = 0, T = 0, O = 0, k = (m + 0.5) * l, P = n(m * l); P < (m + 1) * l; P++)
											for (var E = o(k - (P + 0.5)) / f, M = (y + 0.5) * h, j = E * E, D = n(y * h); D < (y + 1) * h; D++) {
												var A = o(M - (D + 0.5)) / u,
													F = r(j + A * A);
												(F > 1 && F < -1) ||
													((x = 2 * F * F * F - 3 * F * F + 1),
													x > 0 &&
														((A = 4 * (D + P * e)),
														(O += x * p[A + 3]),
														(w += x),
														p[A + 3] < 255 && (x = (x * p[A + 3]) / 250),
														(C += x * p[A]),
														(S += x * p[A + 1]),
														(T += x * p[A + 2]),
														(_ += x)));
											}
										(v[b] = C / _), (v[b + 1] = S / _), (v[b + 2] = T / _), (v[b + 3] = O / w);
									}
								return g;
							},
							toObject: function () {
								return { type: this.type, scaleX: this.scaleX, scaleY: this.scaleY, resizeType: this.resizeType, lanczosLobes: this.lanczosLobes };
							}
						})),
							(e.Image.filters.Resize.fromObject = e.Image.filters.BaseFilter.fromObject);
					})(e),
					(function (t) {
						'use strict';
						var e = t.fabric || (t.fabric = {}),
							i = e.Image.filters,
							n = e.util.createClass;
						(i.Contrast = n(i.BaseFilter, {
							type: 'Contrast',
							fragmentSource:
								'precision highp float;\nuniform sampler2D uTexture;\nuniform float uContrast;\nvarying vec2 vTexCoord;\nvoid main() {\nvec4 color = texture2D(uTexture, vTexCoord);\nfloat contrastF = 1.015 * (uContrast + 1.0) / (1.0 * (1.015 - uContrast));\ncolor.rgb = contrastF * (color.rgb - 0.5) + 0.5;\ngl_FragColor = color;\n}',
							contrast: 0,
							mainParameter: 'contrast',
							applyTo2d: function (t) {
								if (0 !== this.contrast) {
									var e,
										i = t.imageData,
										n = i.data,
										r = n.length,
										o = Math.floor(255 * this.contrast),
										s = (259 * (o + 255)) / (255 * (259 - o));
									for (e = 0; e < r; e += 4) (n[e] = s * (n[e] - 128) + 128), (n[e + 1] = s * (n[e + 1] - 128) + 128), (n[e + 2] = s * (n[e + 2] - 128) + 128);
								}
							},
							getUniformLocations: function (t, e) {
								return { uContrast: t.getUniformLocation(e, 'uContrast') };
							},
							sendUniformData: function (t, e) {
								t.uniform1f(e.uContrast, this.contrast);
							}
						})),
							(e.Image.filters.Contrast.fromObject = e.Image.filters.BaseFilter.fromObject);
					})(e),
					(function (t) {
						'use strict';
						var e = t.fabric || (t.fabric = {}),
							i = e.Image.filters,
							n = e.util.createClass;
						(i.Saturation = n(i.BaseFilter, {
							type: 'Saturation',
							fragmentSource:
								'precision highp float;\nuniform sampler2D uTexture;\nuniform float uSaturation;\nvarying vec2 vTexCoord;\nvoid main() {\nvec4 color = texture2D(uTexture, vTexCoord);\nfloat rgMax = max(color.r, color.g);\nfloat rgbMax = max(rgMax, color.b);\ncolor.r += rgbMax != color.r ? (rgbMax - color.r) * uSaturation : 0.00;\ncolor.g += rgbMax != color.g ? (rgbMax - color.g) * uSaturation : 0.00;\ncolor.b += rgbMax != color.b ? (rgbMax - color.b) * uSaturation : 0.00;\ngl_FragColor = color;\n}',
							saturation: 0,
							mainParameter: 'saturation',
							applyTo2d: function (t) {
								if (0 !== this.saturation) {
									var e,
										i,
										n = t.imageData,
										r = n.data,
										o = r.length,
										s = -this.saturation;
									for (e = 0; e < o; e += 4)
										(i = Math.max(r[e], r[e + 1], r[e + 2])),
											(r[e] += i !== r[e] ? (i - r[e]) * s : 0),
											(r[e + 1] += i !== r[e + 1] ? (i - r[e + 1]) * s : 0),
											(r[e + 2] += i !== r[e + 2] ? (i - r[e + 2]) * s : 0);
								}
							},
							getUniformLocations: function (t, e) {
								return { uSaturation: t.getUniformLocation(e, 'uSaturation') };
							},
							sendUniformData: function (t, e) {
								t.uniform1f(e.uSaturation, -this.saturation);
							}
						})),
							(e.Image.filters.Saturation.fromObject = e.Image.filters.BaseFilter.fromObject);
					})(e),
					(function (t) {
						'use strict';
						var e = t.fabric || (t.fabric = {}),
							i = e.Image.filters,
							n = e.util.createClass;
						(i.Blur = n(i.BaseFilter, {
							type: 'Blur',
							fragmentSource:
								'precision highp float;\nuniform sampler2D uTexture;\nuniform vec2 uDelta;\nvarying vec2 vTexCoord;\nconst float nSamples = 15.0;\nvec3 v3offset = vec3(12.9898, 78.233, 151.7182);\nfloat random(vec3 scale) {\nreturn fract(sin(dot(gl_FragCoord.xyz, scale)) * 43758.5453);\n}\nvoid main() {\nvec4 color = vec4(0.0);\nfloat total = 0.0;\nfloat offset = random(v3offset);\nfor (float t = -nSamples; t <= nSamples; t++) {\nfloat percent = (t + offset - 0.5) / nSamples;\nfloat weight = 1.0 - abs(percent);\ncolor += texture2D(uTexture, vTexCoord + uDelta * percent) * weight;\ntotal += weight;\n}\ngl_FragColor = color / total;\n}',
							blur: 0,
							mainParameter: 'blur',
							applyTo: function (t) {
								t.webgl
									? ((this.aspectRatio = t.sourceWidth / t.sourceHeight),
									  t.passes++,
									  this._setupFrameBuffer(t),
									  (this.horizontal = !0),
									  this.applyToWebGL(t),
									  this._swapTextures(t),
									  this._setupFrameBuffer(t),
									  (this.horizontal = !1),
									  this.applyToWebGL(t),
									  this._swapTextures(t))
									: this.applyTo2d(t);
							},
							applyTo2d: function (t) {
								t.imageData = this.simpleBlur(t);
							},
							simpleBlur: function (t) {
								var i,
									n,
									r = t.filterBackend.resources,
									o = t.imageData.width,
									s = t.imageData.height;
								r.blurLayer1 || ((r.blurLayer1 = e.util.createCanvasElement()), (r.blurLayer2 = e.util.createCanvasElement())),
									(i = r.blurLayer1),
									(n = r.blurLayer2),
									(i.width === o && i.height === s) || ((n.width = i.width = o), (n.height = i.height = s));
								var a,
									c,
									h,
									l,
									u = i.getContext('2d'),
									f = n.getContext('2d'),
									d = 15,
									p = 0.06 * this.blur * 0.5;
								for (u.putImageData(t.imageData, 0, 0), f.clearRect(0, 0, o, s), l = -d; l <= d; l++)
									(a = (Math.random() - 0.5) / 4),
										(c = l / d),
										(h = p * c * o + a),
										(f.globalAlpha = 1 - Math.abs(c)),
										f.drawImage(i, h, a),
										u.drawImage(n, 0, 0),
										(f.globalAlpha = 1),
										f.clearRect(0, 0, n.width, n.height);
								for (l = -d; l <= d; l++)
									(a = (Math.random() - 0.5) / 4),
										(c = l / d),
										(h = p * c * s + a),
										(f.globalAlpha = 1 - Math.abs(c)),
										f.drawImage(i, a, h),
										u.drawImage(n, 0, 0),
										(f.globalAlpha = 1),
										f.clearRect(0, 0, n.width, n.height);
								t.ctx.drawImage(i, 0, 0);
								var g = t.ctx.getImageData(0, 0, i.width, i.height);
								return (u.globalAlpha = 1), u.clearRect(0, 0, i.width, i.height), g;
							},
							getUniformLocations: function (t, e) {
								return { delta: t.getUniformLocation(e, 'uDelta') };
							},
							sendUniformData: function (t, e) {
								var i = this.chooseRightDelta();
								t.uniform2fv(e.delta, i);
							},
							chooseRightDelta: function () {
								var t,
									e = 1,
									i = [0, 0];
								return (
									this.horizontal ? this.aspectRatio > 1 && (e = 1 / this.aspectRatio) : this.aspectRatio < 1 && (e = this.aspectRatio),
									(t = e * this.blur * 0.12),
									this.horizontal ? (i[0] = t) : (i[1] = t),
									i
								);
							}
						})),
							(i.Blur.fromObject = e.Image.filters.BaseFilter.fromObject);
					})(e),
					(function (t) {
						'use strict';
						var e = t.fabric || (t.fabric = {}),
							i = e.Image.filters,
							n = e.util.createClass;
						(i.Gamma = n(i.BaseFilter, {
							type: 'Gamma',
							fragmentSource:
								'precision highp float;\nuniform sampler2D uTexture;\nuniform vec3 uGamma;\nvarying vec2 vTexCoord;\nvoid main() {\nvec4 color = texture2D(uTexture, vTexCoord);\nvec3 correction = (1.0 / uGamma);\ncolor.r = pow(color.r, correction.r);\ncolor.g = pow(color.g, correction.g);\ncolor.b = pow(color.b, correction.b);\ngl_FragColor = color;\ngl_FragColor.rgb *= color.a;\n}',
							gamma: [1, 1, 1],
							mainParameter: 'gamma',
							initialize: function (t) {
								(this.gamma = [1, 1, 1]), i.BaseFilter.prototype.initialize.call(this, t);
							},
							applyTo2d: function (t) {
								var e,
									i = t.imageData,
									n = i.data,
									r = this.gamma,
									o = n.length,
									s = 1 / r[0],
									a = 1 / r[1],
									c = 1 / r[2];
								for (this.rVals || ((this.rVals = new Uint8Array(256)), (this.gVals = new Uint8Array(256)), (this.bVals = new Uint8Array(256))), e = 0, o = 256; e < o; e++)
									(this.rVals[e] = 255 * Math.pow(e / 255, s)), (this.gVals[e] = 255 * Math.pow(e / 255, a)), (this.bVals[e] = 255 * Math.pow(e / 255, c));
								for (e = 0, o = n.length; e < o; e += 4) (n[e] = this.rVals[n[e]]), (n[e + 1] = this.gVals[n[e + 1]]), (n[e + 2] = this.bVals[n[e + 2]]);
							},
							getUniformLocations: function (t, e) {
								return { uGamma: t.getUniformLocation(e, 'uGamma') };
							},
							sendUniformData: function (t, e) {
								t.uniform3fv(e.uGamma, this.gamma);
							}
						})),
							(e.Image.filters.Gamma.fromObject = e.Image.filters.BaseFilter.fromObject);
					})(e),
					(function (t) {
						'use strict';
						var e = t.fabric || (t.fabric = {}),
							i = e.Image.filters,
							n = e.util.createClass;
						(i.Composed = n(i.BaseFilter, {
							type: 'Composed',
							subFilters: [],
							initialize: function (t) {
								this.callSuper('initialize', t), (this.subFilters = this.subFilters.slice(0));
							},
							applyTo: function (t) {
								(t.passes += this.subFilters.length - 1),
									this.subFilters.forEach(function (e) {
										e.applyTo(t);
									});
							},
							toObject: function () {
								return e.util.object.extend(this.callSuper('toObject'), {
									subFilters: this.subFilters.map(function (t) {
										return t.toObject();
									})
								});
							},
							isNeutralState: function () {
								return !this.subFilters.some(function (t) {
									return !t.isNeutralState();
								});
							}
						})),
							(e.Image.filters.Composed.fromObject = function (t, i) {
								var n = t.subFilters || [],
									r = n.map(function (t) {
										return new e.Image.filters[t.type](t);
									}),
									o = new e.Image.filters.Composed({ subFilters: r });
								return i && i(o), o;
							});
					})(e),
					(function (t) {
						'use strict';
						var e = t.fabric || (t.fabric = {}),
							i = e.Image.filters,
							n = e.util.createClass;
						(i.HueRotation = n(i.ColorMatrix, {
							type: 'HueRotation',
							rotation: 0,
							mainParameter: 'rotation',
							calculateMatrix: function () {
								var t = this.rotation * Math.PI,
									i = e.util.cos(t),
									n = e.util.sin(t),
									r = 1 / 3,
									o = Math.sqrt(r) * n,
									s = 1 - i;
								(this.matrix = [1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0]),
									(this.matrix[0] = i + s / 3),
									(this.matrix[1] = r * s - o),
									(this.matrix[2] = r * s + o),
									(this.matrix[5] = r * s + o),
									(this.matrix[6] = i + r * s),
									(this.matrix[7] = r * s - o),
									(this.matrix[10] = r * s - o),
									(this.matrix[11] = r * s + o),
									(this.matrix[12] = i + r * s);
							},
							isNeutralState: function (t) {
								return this.calculateMatrix(), i.BaseFilter.prototype.isNeutralState.call(this, t);
							},
							applyTo: function (t) {
								this.calculateMatrix(), i.BaseFilter.prototype.applyTo.call(this, t);
							}
						})),
							(e.Image.filters.HueRotation.fromObject = e.Image.filters.BaseFilter.fromObject);
					})(e),
					(function (t) {
						'use strict';
						var e = t.fabric || (t.fabric = {}),
							i = e.util.object.clone;
						if (e.Text) e.warn('fabric.Text is already defined');
						else {
							var n =
								'fontFamily fontWeight fontSize text underline overline linethrough textAlign fontStyle lineHeight textBackgroundColor charSpacing styles direction path pathStartOffset pathSide pathAlign'.split(
									' '
								);
							(e.Text = e.util.createClass(e.Object, {
								_dimensionAffectingProps: [
									'fontSize',
									'fontWeight',
									'fontFamily',
									'fontStyle',
									'lineHeight',
									'text',
									'charSpacing',
									'textAlign',
									'styles',
									'path',
									'pathStartOffset',
									'pathSide',
									'pathAlign'
								],
								_reNewline: /\r?\n/,
								_reSpacesAndTabs: /[ \t\r]/g,
								_reSpaceAndTab: /[ \t\r]/,
								_reWords: /\S+/g,
								type: 'text',
								fontSize: 40,
								fontWeight: 'normal',
								fontFamily: 'Times New Roman',
								underline: !1,
								overline: !1,
								linethrough: !1,
								textAlign: 'left',
								fontStyle: 'normal',
								lineHeight: 1.16,
								superscript: { size: 0.6, baseline: -0.35 },
								subscript: { size: 0.6, baseline: 0.11 },
								textBackgroundColor: '',
								stateProperties: e.Object.prototype.stateProperties.concat(n),
								cacheProperties: e.Object.prototype.cacheProperties.concat(n),
								stroke: null,
								shadow: null,
								path: null,
								pathStartOffset: 0,
								pathSide: 'left',
								pathAlign: 'baseline',
								_fontSizeFraction: 0.222,
								offsets: { underline: 0.1, linethrough: -0.315, overline: -0.88 },
								_fontSizeMult: 1.13,
								charSpacing: 0,
								styles: null,
								_measuringContext: null,
								deltaY: 0,
								direction: 'ltr',
								_styleProperties: [
									'stroke',
									'strokeWidth',
									'fill',
									'fontFamily',
									'fontSize',
									'fontWeight',
									'fontStyle',
									'underline',
									'overline',
									'linethrough',
									'deltaY',
									'textBackgroundColor'
								],
								__charBounds: [],
								CACHE_FONT_SIZE: 400,
								MIN_TEXT_WIDTH: 2,
								initialize: function (t, e) {
									(this.styles = (e && e.styles) || {}),
										(this.text = t),
										(this.__skipDimension = !0),
										this.callSuper('initialize', e),
										this.path && this.setPathInfo(),
										(this.__skipDimension = !1),
										this.initDimensions(),
										this.setCoords(),
										this.setupState({ propertySet: '_dimensionAffectingProps' });
								},
								setPathInfo: function () {
									var t = this.path;
									t && (t.segmentsInfo = e.util.getPathSegmentsInfo(t.path));
								},
								getMeasuringContext: function () {
									return (
										e._measuringContext || (e._measuringContext = (this.canvas && this.canvas.contextCache) || e.util.createCanvasElement().getContext('2d')), e._measuringContext
									);
								},
								_splitText: function () {
									var t = this._splitTextIntoLines(this.text);
									return (this.textLines = t.lines), (this._textLines = t.graphemeLines), (this._unwrappedTextLines = t._unwrappedLines), (this._text = t.graphemeText), t;
								},
								initDimensions: function () {
									this.__skipDimension ||
										(this._splitText(),
										this._clearCache(),
										this.path
											? ((this.width = this.path.width), (this.height = this.path.height))
											: ((this.width = this.calcTextWidth() || this.cursorWidth || this.MIN_TEXT_WIDTH), (this.height = this.calcTextHeight())),
										-1 !== this.textAlign.indexOf('justify') && this.enlargeSpaces(),
										this.saveState({ propertySet: '_dimensionAffectingProps' }));
								},
								enlargeSpaces: function () {
									for (var t, e, i, n, r, o, s, a = 0, c = this._textLines.length; a < c; a++)
										if (
											('justify' === this.textAlign || (a !== c - 1 && !this.isEndOfWrapping(a))) &&
											((n = 0), (r = this._textLines[a]), (e = this.getLineWidth(a)), e < this.width && (s = this.textLines[a].match(this._reSpacesAndTabs)))
										) {
											(i = s.length), (t = (this.width - e) / i);
											for (var h = 0, l = r.length; h <= l; h++)
												(o = this.__charBounds[a][h]), this._reSpaceAndTab.test(r[h]) ? ((o.width += t), (o.kernedWidth += t), (o.left += n), (n += t)) : (o.left += n);
										}
								},
								isEndOfWrapping: function (t) {
									return t === this._textLines.length - 1;
								},
								missingNewlineOffset: function () {
									return 1;
								},
								toString: function () {
									return '#<fabric.Text (' + this.complexity() + '): { "text": "' + this.text + '", "fontFamily": "' + this.fontFamily + '" }>';
								},
								_getCacheCanvasDimensions: function () {
									var t = this.callSuper('_getCacheCanvasDimensions'),
										e = this.fontSize;
									return (t.width += e * t.zoomX), (t.height += e * t.zoomY), t;
								},
								_render: function (t) {
									var e = this.path;
									e && !e.isNotVisible() && e._render(t),
										this._setTextStyles(t),
										this._renderTextLinesBackground(t),
										this._renderTextDecoration(t, 'underline'),
										this._renderText(t),
										this._renderTextDecoration(t, 'overline'),
										this._renderTextDecoration(t, 'linethrough');
								},
								_renderText: function (t) {
									'stroke' === this.paintFirst ? (this._renderTextStroke(t), this._renderTextFill(t)) : (this._renderTextFill(t), this._renderTextStroke(t));
								},
								_setTextStyles: function (t, e, i) {
									if (((t.textBaseline = 'alphabetical'), this.path))
										switch (this.pathAlign) {
											case 'center':
												t.textBaseline = 'middle';
												break;
											case 'ascender':
												t.textBaseline = 'top';
												break;
											case 'descender':
												t.textBaseline = 'bottom';
												break;
										}
									t.font = this._getFontDeclaration(e, i);
								},
								calcTextWidth: function () {
									for (var t = this.getLineWidth(0), e = 1, i = this._textLines.length; e < i; e++) {
										var n = this.getLineWidth(e);
										n > t && (t = n);
									}
									return t;
								},
								_renderTextLine: function (t, e, i, n, r, o) {
									this._renderChars(t, e, i, n, r, o);
								},
								_renderTextLinesBackground: function (t) {
									if (this.textBackgroundColor || this.styleHas('textBackgroundColor')) {
										for (
											var e,
												i,
												n,
												r,
												o,
												s,
												a,
												c = t.fillStyle,
												h = this._getLeftOffset(),
												l = this._getTopOffset(),
												u = 0,
												f = 0,
												d = this.path,
												p = 0,
												g = this._textLines.length;
											p < g;
											p++
										)
											if (((e = this.getHeightOfLine(p)), this.textBackgroundColor || this.styleHas('textBackgroundColor', p))) {
												(n = this._textLines[p]), (i = this._getLineLeftOffset(p)), (f = 0), (u = 0), (r = this.getValueOfPropertyAt(p, 0, 'textBackgroundColor'));
												for (var v = 0, m = n.length; v < m; v++)
													(o = this.__charBounds[p][v]),
														(s = this.getValueOfPropertyAt(p, v, 'textBackgroundColor')),
														d
															? (t.save(),
															  t.translate(o.renderLeft, o.renderTop),
															  t.rotate(o.angle),
															  (t.fillStyle = s),
															  s && t.fillRect(-o.width / 2, (-e / this.lineHeight) * (1 - this._fontSizeFraction), o.width, e / this.lineHeight),
															  t.restore())
															: s !== r
															? ((a = h + i + u),
															  'rtl' === this.direction && (a = this.width - a - f),
															  (t.fillStyle = r),
															  r && t.fillRect(a, l, f, e / this.lineHeight),
															  (u = o.left),
															  (f = o.width),
															  (r = s))
															: (f += o.kernedWidth);
												s && !d && ((a = h + i + u), 'rtl' === this.direction && (a = this.width - a - f), (t.fillStyle = s), t.fillRect(a, l, f, e / this.lineHeight)),
													(l += e);
											} else l += e;
										(t.fillStyle = c), this._removeShadow(t);
									}
								},
								getFontCache: function (t) {
									var i = t.fontFamily.toLowerCase();
									e.charWidthsCache[i] || (e.charWidthsCache[i] = {});
									var n = e.charWidthsCache[i],
										r = t.fontStyle.toLowerCase() + '_' + (t.fontWeight + '').toLowerCase();
									return n[r] || (n[r] = {}), n[r];
								},
								_measureChar: function (t, e, i, n) {
									var r,
										o,
										s,
										a,
										c = this.getFontCache(e),
										h = this._getFontDeclaration(e),
										l = this._getFontDeclaration(n),
										u = i + t,
										f = h === l,
										d = e.fontSize / this.CACHE_FONT_SIZE;
									if (
										(i && void 0 !== c[i] && (s = c[i]),
										void 0 !== c[t] && (a = r = c[t]),
										f && void 0 !== c[u] && ((o = c[u]), (a = o - s)),
										void 0 === r || void 0 === s || void 0 === o)
									) {
										var p = this.getMeasuringContext();
										this._setTextStyles(p, e, !0);
									}
									return (
										void 0 === r && ((a = r = p.measureText(t).width), (c[t] = r)),
										void 0 === s && f && i && ((s = p.measureText(i).width), (c[i] = s)),
										f && void 0 === o && ((o = p.measureText(u).width), (c[u] = o), (a = o - s)),
										{ width: r * d, kernedWidth: a * d }
									);
								},
								getHeightOfChar: function (t, e) {
									return this.getValueOfPropertyAt(t, e, 'fontSize');
								},
								measureLine: function (t) {
									var e = this._measureLine(t);
									return 0 !== this.charSpacing && (e.width -= this._getWidthOfCharSpacing()), e.width < 0 && (e.width = 0), e;
								},
								_measureLine: function (t) {
									var i,
										n,
										r,
										o,
										s,
										a,
										c = 0,
										h = this._textLines[t],
										l = 0,
										u = new Array(h.length),
										f = 0,
										d = this.path,
										p = 'right' === this.pathSide;
									for (this.__charBounds[t] = u, i = 0; i < h.length; i++) (n = h[i]), (o = this._getGraphemeBox(n, t, i, r)), (u[i] = o), (c += o.kernedWidth), (r = n);
									if (((u[i] = { left: o ? o.left + o.width : 0, width: 0, kernedWidth: 0, height: this.fontSize }), d)) {
										switch (
											((a = d.segmentsInfo[d.segmentsInfo.length - 1].length),
											(s = e.util.getPointOnPath(d.path, 0, d.segmentsInfo)),
											(s.x += d.pathOffset.x),
											(s.y += d.pathOffset.y),
											this.textAlign)
										) {
											case 'left':
												f = p ? a - c : 0;
												break;
											case 'center':
												f = (a - c) / 2;
												break;
											case 'right':
												f = p ? 0 : a - c;
												break;
										}
										for (f += this.pathStartOffset * (p ? -1 : 1), i = p ? h.length - 1 : 0; p ? i >= 0 : i < h.length; p ? i-- : i++)
											(o = u[i]), f > a ? (f %= a) : f < 0 && (f += a), this._setGraphemeOnPath(f, o, s), (f += o.kernedWidth);
									}
									return { width: c, numOfSpaces: l };
								},
								_setGraphemeOnPath: function (t, i, n) {
									var r = t + i.kernedWidth / 2,
										o = this.path,
										s = e.util.getPointOnPath(o.path, r, o.segmentsInfo);
									(i.renderLeft = s.x - n.x), (i.renderTop = s.y - n.y), (i.angle = s.angle + ('right' === this.pathSide ? Math.PI : 0));
								},
								_getGraphemeBox: function (t, e, i, n, r) {
									var o,
										s = this.getCompleteStyleDeclaration(e, i),
										a = n ? this.getCompleteStyleDeclaration(e, i - 1) : {},
										c = this._measureChar(t, s, n, a),
										h = c.kernedWidth,
										l = c.width;
									0 !== this.charSpacing && ((o = this._getWidthOfCharSpacing()), (l += o), (h += o));
									var u = { width: l, left: 0, height: s.fontSize, kernedWidth: h, deltaY: s.deltaY };
									if (i > 0 && !r) {
										var f = this.__charBounds[e][i - 1];
										u.left = f.left + f.width + c.kernedWidth - c.width;
									}
									return u;
								},
								getHeightOfLine: function (t) {
									if (this.__lineHeights[t]) return this.__lineHeights[t];
									for (var e = this._textLines[t], i = this.getHeightOfChar(t, 0), n = 1, r = e.length; n < r; n++) i = Math.max(this.getHeightOfChar(t, n), i);
									return (this.__lineHeights[t] = i * this.lineHeight * this._fontSizeMult);
								},
								calcTextHeight: function () {
									for (var t, e = 0, i = 0, n = this._textLines.length; i < n; i++) (t = this.getHeightOfLine(i)), (e += i === n - 1 ? t / this.lineHeight : t);
									return e;
								},
								_getLeftOffset: function () {
									return 'ltr' === this.direction ? -this.width / 2 : this.width / 2;
								},
								_getTopOffset: function () {
									return -this.height / 2;
								},
								_renderTextCommon: function (t, e) {
									t.save();
									for (var i = 0, n = this._getLeftOffset(), r = this._getTopOffset(), o = 0, s = this._textLines.length; o < s; o++) {
										var a = this.getHeightOfLine(o),
											c = a / this.lineHeight,
											h = this._getLineLeftOffset(o);
										this._renderTextLine(e, t, this._textLines[o], n + h, r + i + c, o), (i += a);
									}
									t.restore();
								},
								_renderTextFill: function (t) {
									(this.fill || this.styleHas('fill')) && this._renderTextCommon(t, 'fillText');
								},
								_renderTextStroke: function (t) {
									((this.stroke && 0 !== this.strokeWidth) || !this.isEmptyStyles()) &&
										(this.shadow && !this.shadow.affectStroke && this._removeShadow(t),
										t.save(),
										this._setLineDash(t, this.strokeDashArray),
										t.beginPath(),
										this._renderTextCommon(t, 'strokeText'),
										t.closePath(),
										t.restore());
								},
								_renderChars: function (t, i, n, r, o, s) {
									var a,
										c,
										h,
										l,
										u,
										f = this.getHeightOfLine(s),
										d = -1 !== this.textAlign.indexOf('justify'),
										p = '',
										g = 0,
										v = this.path,
										m = !d && 0 === this.charSpacing && this.isEmptyStyles(s) && !v,
										y = 'ltr' === this.direction,
										b = 'ltr' === this.direction ? 1 : -1,
										x = i.canvas.getAttribute('dir');
									if (
										(i.save(),
										x !== this.direction && (i.canvas.setAttribute('dir', y ? 'ltr' : 'rtl'), (i.direction = y ? 'ltr' : 'rtl'), (i.textAlign = y ? 'left' : 'right')),
										(o -= (f * this._fontSizeFraction) / this.lineHeight),
										m)
									)
										return this._renderChar(t, i, s, 0, n.join(''), r, o, f), void i.restore();
									for (var _ = 0, w = n.length - 1; _ <= w; _++)
										(l = _ === w || this.charSpacing || v),
											(p += n[_]),
											(h = this.__charBounds[s][_]),
											0 === g ? ((r += b * (h.kernedWidth - h.width)), (g += h.width)) : (g += h.kernedWidth),
											d && !l && this._reSpaceAndTab.test(n[_]) && (l = !0),
											l || ((a = a || this.getCompleteStyleDeclaration(s, _)), (c = this.getCompleteStyleDeclaration(s, _ + 1)), (l = e.util.hasStyleChanged(a, c, !1))),
											l &&
												(v
													? (i.save(), i.translate(h.renderLeft, h.renderTop), i.rotate(h.angle), this._renderChar(t, i, s, _, p, -g / 2, 0, f), i.restore())
													: ((u = r), this._renderChar(t, i, s, _, p, u, o, f)),
												(p = ''),
												(a = c),
												(r += b * g),
												(g = 0));
									i.restore();
								},
								_applyPatternGradientTransformText: function (t) {
									var i,
										n = e.util.createCanvasElement(),
										r = this.width + this.strokeWidth,
										o = this.height + this.strokeWidth;
									return (
										(n.width = r),
										(n.height = o),
										(i = n.getContext('2d')),
										i.beginPath(),
										i.moveTo(0, 0),
										i.lineTo(r, 0),
										i.lineTo(r, o),
										i.lineTo(0, o),
										i.closePath(),
										i.translate(r / 2, o / 2),
										(i.fillStyle = t.toLive(i)),
										this._applyPatternGradientTransform(i, t),
										i.fill(),
										i.createPattern(n, 'no-repeat')
									);
								},
								handleFiller: function (t, e, i) {
									var n, r;
									return i.toLive
										? 'percentage' === i.gradientUnits || i.gradientTransform || i.patternTransform
											? ((n = -this.width / 2), (r = -this.height / 2), t.translate(n, r), (t[e] = this._applyPatternGradientTransformText(i)), { offsetX: n, offsetY: r })
											: ((t[e] = i.toLive(t, this)), this._applyPatternGradientTransform(t, i))
										: ((t[e] = i), { offsetX: 0, offsetY: 0 });
								},
								_setStrokeStyles: function (t, e) {
									return (
										(t.lineWidth = e.strokeWidth),
										(t.lineCap = this.strokeLineCap),
										(t.lineDashOffset = this.strokeDashOffset),
										(t.lineJoin = this.strokeLineJoin),
										(t.miterLimit = this.strokeMiterLimit),
										this.handleFiller(t, 'strokeStyle', e.stroke)
									);
								},
								_setFillStyles: function (t, e) {
									return this.handleFiller(t, 'fillStyle', e.fill);
								},
								_renderChar: function (t, e, i, n, r, o, s) {
									var a,
										c,
										h = this._getStyleDeclaration(i, n),
										l = this.getCompleteStyleDeclaration(i, n),
										u = 'fillText' === t && l.fill,
										f = 'strokeText' === t && l.stroke && l.strokeWidth;
									(f || u) &&
										(e.save(),
										u && (a = this._setFillStyles(e, l)),
										f && (c = this._setStrokeStyles(e, l)),
										(e.font = this._getFontDeclaration(l)),
										h && h.textBackgroundColor && this._removeShadow(e),
										h && h.deltaY && (s += h.deltaY),
										u && e.fillText(r, o - a.offsetX, s - a.offsetY),
										f && e.strokeText(r, o - c.offsetX, s - c.offsetY),
										e.restore());
								},
								setSuperscript: function (t, e) {
									return this._setScript(t, e, this.superscript);
								},
								setSubscript: function (t, e) {
									return this._setScript(t, e, this.subscript);
								},
								_setScript: function (t, e, i) {
									var n = this.get2DCursorLocation(t, !0),
										r = this.getValueOfPropertyAt(n.lineIndex, n.charIndex, 'fontSize'),
										o = this.getValueOfPropertyAt(n.lineIndex, n.charIndex, 'deltaY'),
										s = { fontSize: r * i.size, deltaY: o + r * i.baseline };
									return this.setSelectionStyles(s, t, e), this;
								},
								_getLineLeftOffset: function (t) {
									var e = this.getLineWidth(t),
										i = this.width - e,
										n = this.textAlign,
										r = this.direction,
										o = 0,
										s = this.isEndOfWrapping(t);
									return 'justify' === n || ('justify-center' === n && !s) || ('justify-right' === n && !s) || ('justify-left' === n && !s)
										? 0
										: ('center' === n && (o = i / 2),
										  'right' === n && (o = i),
										  'justify-center' === n && (o = i / 2),
										  'justify-right' === n && (o = i),
										  'rtl' === r && (o -= i),
										  o);
								},
								_clearCache: function () {
									(this.__lineWidths = []), (this.__lineHeights = []), (this.__charBounds = []);
								},
								_shouldClearDimensionCache: function () {
									var t = this._forceClearCache;
									return t || (t = this.hasStateChanged('_dimensionAffectingProps')), t && ((this.dirty = !0), (this._forceClearCache = !1)), t;
								},
								getLineWidth: function (t) {
									if (void 0 !== this.__lineWidths[t]) return this.__lineWidths[t];
									var e = this.measureLine(t),
										i = e.width;
									return (this.__lineWidths[t] = i), i;
								},
								_getWidthOfCharSpacing: function () {
									return 0 !== this.charSpacing ? (this.fontSize * this.charSpacing) / 1e3 : 0;
								},
								getValueOfPropertyAt: function (t, e, i) {
									var n = this._getStyleDeclaration(t, e);
									return n && 'undefined' !== typeof n[i] ? n[i] : this[i];
								},
								_renderTextDecoration: function (t, e) {
									if (this[e] || this.styleHas(e)) {
										for (
											var i,
												n,
												r,
												o,
												s,
												a,
												c,
												h,
												l,
												u,
												f,
												d,
												p,
												g,
												v,
												m,
												y = this._getLeftOffset(),
												b = this._getTopOffset(),
												x = this.path,
												_ = this._getWidthOfCharSpacing(),
												w = this.offsets[e],
												C = 0,
												S = this._textLines.length;
											C < S;
											C++
										)
											if (((i = this.getHeightOfLine(C)), this[e] || this.styleHas(e, C))) {
												(c = this._textLines[C]),
													(g = i / this.lineHeight),
													(o = this._getLineLeftOffset(C)),
													(u = 0),
													(f = 0),
													(h = this.getValueOfPropertyAt(C, 0, e)),
													(m = this.getValueOfPropertyAt(C, 0, 'fill')),
													(l = b + g * (1 - this._fontSizeFraction)),
													(n = this.getHeightOfChar(C, 0)),
													(s = this.getValueOfPropertyAt(C, 0, 'deltaY'));
												for (var T = 0, O = c.length; T < O; T++)
													if (
														((d = this.__charBounds[C][T]),
														(p = this.getValueOfPropertyAt(C, T, e)),
														(v = this.getValueOfPropertyAt(C, T, 'fill')),
														(r = this.getHeightOfChar(C, T)),
														(a = this.getValueOfPropertyAt(C, T, 'deltaY')),
														x && p && v)
													)
														t.save(),
															(t.fillStyle = m),
															t.translate(d.renderLeft, d.renderTop),
															t.rotate(d.angle),
															t.fillRect(-d.kernedWidth / 2, w * r + a, d.kernedWidth, this.fontSize / 15),
															t.restore();
													else if ((p !== h || v !== m || r !== n || a !== s) && f > 0) {
														var k = y + o + u;
														'rtl' === this.direction && (k = this.width - k - f),
															h && m && ((t.fillStyle = m), t.fillRect(k, l + w * n + s, f, this.fontSize / 15)),
															(u = d.left),
															(f = d.width),
															(h = p),
															(m = v),
															(n = r),
															(s = a);
													} else f += d.kernedWidth;
												k = y + o + u;
												'rtl' === this.direction && (k = this.width - k - f), (t.fillStyle = v), p && v && t.fillRect(k, l + w * n + s, f - _, this.fontSize / 15), (b += i);
											} else b += i;
										this._removeShadow(t);
									}
								},
								_getFontDeclaration: function (t, i) {
									var n = t || this,
										r = this.fontFamily,
										o = e.Text.genericFonts.indexOf(r.toLowerCase()) > -1,
										s = void 0 === r || r.indexOf("'") > -1 || r.indexOf(',') > -1 || r.indexOf('"') > -1 || o ? n.fontFamily : '"' + n.fontFamily + '"';
									return [e.isLikelyNode ? n.fontWeight : n.fontStyle, e.isLikelyNode ? n.fontStyle : n.fontWeight, i ? this.CACHE_FONT_SIZE + 'px' : n.fontSize + 'px', s].join(' ');
								},
								render: function (t) {
									this.visible &&
										((this.canvas && this.canvas.skipOffscreen && !this.group && !this.isOnScreen()) ||
											(this._shouldClearDimensionCache() && this.initDimensions(), this.callSuper('render', t)));
								},
								_splitTextIntoLines: function (t) {
									for (var i = t.split(this._reNewline), n = new Array(i.length), r = ['\n'], o = [], s = 0; s < i.length; s++)
										(n[s] = e.util.string.graphemeSplit(i[s])), (o = o.concat(n[s], r));
									return o.pop(), { _unwrappedLines: n, lines: i, graphemeText: o, graphemeLines: n };
								},
								toObject: function (t) {
									var i = n.concat(t),
										r = this.callSuper('toObject', i);
									return (r.styles = e.util.stylesToArray(this.styles, this.text)), r.path && (r.path = this.path.toObject()), r;
								},
								set: function (t, e) {
									this.callSuper('set', t, e);
									var i = !1,
										n = !1;
									if ('object' === typeof t) for (var r in t) 'path' === r && this.setPathInfo(), (i = i || -1 !== this._dimensionAffectingProps.indexOf(r)), (n = n || 'path' === r);
									else (i = -1 !== this._dimensionAffectingProps.indexOf(t)), (n = 'path' === t);
									return n && this.setPathInfo(), i && (this.initDimensions(), this.setCoords()), this;
								},
								complexity: function () {
									return 1;
								}
							})),
								(e.Text.ATTRIBUTE_NAMES = e.SHARED_ATTRIBUTES.concat('x y dx dy font-family font-style font-weight font-size letter-spacing text-decoration text-anchor'.split(' '))),
								(e.Text.DEFAULT_SVG_FONT_SIZE = 16),
								(e.Text.fromElement = function (t, n, r) {
									if (!t) return n(null);
									var o = e.parseAttributes(t, e.Text.ATTRIBUTE_NAMES),
										s = o.textAnchor || 'left';
									if (((r = e.util.object.extend(r ? i(r) : {}, o)), (r.top = r.top || 0), (r.left = r.left || 0), o.textDecoration)) {
										var a = o.textDecoration;
										-1 !== a.indexOf('underline') && (r.underline = !0),
											-1 !== a.indexOf('overline') && (r.overline = !0),
											-1 !== a.indexOf('line-through') && (r.linethrough = !0),
											delete r.textDecoration;
									}
									'dx' in o && (r.left += o.dx), 'dy' in o && (r.top += o.dy), 'fontSize' in r || (r.fontSize = e.Text.DEFAULT_SVG_FONT_SIZE);
									var c = '';
									'textContent' in t
										? (c = t.textContent)
										: 'firstChild' in t && null !== t.firstChild && 'data' in t.firstChild && null !== t.firstChild.data && (c = t.firstChild.data),
										(c = c.replace(/^\s+|\s+$|\n+/g, '').replace(/\s+/g, ' '));
									var h = r.strokeWidth;
									r.strokeWidth = 0;
									var l = new e.Text(c, r),
										u = l.getScaledHeight() / l.height,
										f = (l.height + l.strokeWidth) * l.lineHeight - l.height,
										d = f * u,
										p = l.getScaledHeight() + d,
										g = 0;
									'center' === s && (g = l.getScaledWidth() / 2),
										'right' === s && (g = l.getScaledWidth()),
										l.set({ left: l.left - g, top: l.top - (p - l.fontSize * (0.07 + l._fontSizeFraction)) / l.lineHeight, strokeWidth: 'undefined' !== typeof h ? h : 1 }),
										n(l);
								}),
								(e.Text.fromObject = function (t, n) {
									var r = i(t),
										o = t.path;
									return (
										delete r.path,
										e.Object._fromObject(
											'Text',
											r,
											function (i) {
												(i.styles = e.util.stylesFromArray(t.styles, t.text)),
													o
														? e.Object._fromObject(
																'Path',
																o,
																function (t) {
																	i.set('path', t), n(i);
																},
																'path'
														  )
														: n(i);
											},
											'text'
										)
									);
								}),
								(e.Text.genericFonts = ['sans-serif', 'serif', 'cursive', 'fantasy', 'monospace']),
								e.util.createAccessors && e.util.createAccessors(e.Text);
						}
					})(e),
					(function () {
						n.util.object.extend(n.Text.prototype, {
							isEmptyStyles: function (t) {
								if (!this.styles) return !0;
								if ('undefined' !== typeof t && !this.styles[t]) return !0;
								var e = 'undefined' === typeof t ? this.styles : { line: this.styles[t] };
								for (var i in e) for (var n in e[i]) for (var r in e[i][n]) return !1;
								return !0;
							},
							styleHas: function (t, e) {
								if (!this.styles || !t || '' === t) return !1;
								if ('undefined' !== typeof e && !this.styles[e]) return !1;
								var i = 'undefined' === typeof e ? this.styles : { 0: this.styles[e] };
								for (var n in i) for (var r in i[n]) if ('undefined' !== typeof i[n][r][t]) return !0;
								return !1;
							},
							cleanStyle: function (t) {
								if (!this.styles || !t || '' === t) return !1;
								var e,
									i,
									n = this.styles,
									r = 0,
									o = !0,
									s = 0;
								for (var a in n) {
									for (var c in ((e = 0), n[a])) {
										var h = n[a][c],
											l = h.hasOwnProperty(t);
										r++, l ? (i ? h[t] !== i && (o = !1) : (i = h[t]), h[t] === this[t] && delete h[t]) : (o = !1), 0 !== Object.keys(h).length ? e++ : delete n[a][c];
									}
									0 === e && delete n[a];
								}
								for (var u = 0; u < this._textLines.length; u++) s += this._textLines[u].length;
								o && r === s && ((this[t] = i), this.removeStyle(t));
							},
							removeStyle: function (t) {
								if (this.styles && t && '' !== t) {
									var e,
										i,
										n,
										r = this.styles;
									for (i in r) {
										for (n in ((e = r[i]), e)) delete e[n][t], 0 === Object.keys(e[n]).length && delete e[n];
										0 === Object.keys(e).length && delete r[i];
									}
								}
							},
							_extendStyles: function (t, e) {
								var i = this.get2DCursorLocation(t);
								this._getLineStyle(i.lineIndex) || this._setLineStyle(i.lineIndex),
									this._getStyleDeclaration(i.lineIndex, i.charIndex) || this._setStyleDeclaration(i.lineIndex, i.charIndex, {}),
									n.util.object.extend(this._getStyleDeclaration(i.lineIndex, i.charIndex), e);
							},
							get2DCursorLocation: function (t, e) {
								'undefined' === typeof t && (t = this.selectionStart);
								for (var i = e ? this._unwrappedTextLines : this._textLines, n = i.length, r = 0; r < n; r++) {
									if (t <= i[r].length) return { lineIndex: r, charIndex: t };
									t -= i[r].length + this.missingNewlineOffset(r);
								}
								return { lineIndex: r - 1, charIndex: i[r - 1].length < t ? i[r - 1].length : t };
							},
							getSelectionStyles: function (t, e, i) {
								'undefined' === typeof t && (t = this.selectionStart || 0), 'undefined' === typeof e && (e = this.selectionEnd || t);
								for (var n = [], r = t; r < e; r++) n.push(this.getStyleAtPosition(r, i));
								return n;
							},
							getStyleAtPosition: function (t, e) {
								var i = this.get2DCursorLocation(t),
									n = e ? this.getCompleteStyleDeclaration(i.lineIndex, i.charIndex) : this._getStyleDeclaration(i.lineIndex, i.charIndex);
								return n || {};
							},
							setSelectionStyles: function (t, e, i) {
								'undefined' === typeof e && (e = this.selectionStart || 0), 'undefined' === typeof i && (i = this.selectionEnd || e);
								for (var n = e; n < i; n++) this._extendStyles(n, t);
								return (this._forceClearCache = !0), this;
							},
							_getStyleDeclaration: function (t, e) {
								var i = this.styles && this.styles[t];
								return i ? i[e] : null;
							},
							getCompleteStyleDeclaration: function (t, e) {
								for (var i, n = this._getStyleDeclaration(t, e) || {}, r = {}, o = 0; o < this._styleProperties.length; o++)
									(i = this._styleProperties[o]), (r[i] = 'undefined' === typeof n[i] ? this[i] : n[i]);
								return r;
							},
							_setStyleDeclaration: function (t, e, i) {
								this.styles[t][e] = i;
							},
							_deleteStyleDeclaration: function (t, e) {
								delete this.styles[t][e];
							},
							_getLineStyle: function (t) {
								return !!this.styles[t];
							},
							_setLineStyle: function (t) {
								this.styles[t] = {};
							},
							_deleteLineStyle: function (t) {
								delete this.styles[t];
							}
						});
					})(),
					(function () {
						function t(t) {
							t.textDecoration &&
								(t.textDecoration.indexOf('underline') > -1 && (t.underline = !0),
								t.textDecoration.indexOf('line-through') > -1 && (t.linethrough = !0),
								t.textDecoration.indexOf('overline') > -1 && (t.overline = !0),
								delete t.textDecoration);
						}
						(n.IText = n.util.createClass(n.Text, n.Observable, {
							type: 'i-text',
							selectionStart: 0,
							selectionEnd: 0,
							selectionColor: 'rgba(17,119,255,0.3)',
							isEditing: !1,
							editable: !0,
							editingBorderColor: 'rgba(102,153,255,0.25)',
							cursorWidth: 2,
							cursorColor: '',
							cursorDelay: 1e3,
							cursorDuration: 600,
							caching: !0,
							hiddenTextareaContainer: null,
							_reSpace: /\s|\n/,
							_currentCursorOpacity: 0,
							_selectionDirection: null,
							_abortCursorAnimation: !1,
							__widthOfSpace: [],
							inCompositionMode: !1,
							initialize: function (t, e) {
								this.callSuper('initialize', t, e), this.initBehavior();
							},
							setSelectionStart: function (t) {
								(t = Math.max(t, 0)), this._updateAndFire('selectionStart', t);
							},
							setSelectionEnd: function (t) {
								(t = Math.min(t, this.text.length)), this._updateAndFire('selectionEnd', t);
							},
							_updateAndFire: function (t, e) {
								this[t] !== e && (this._fireSelectionChanged(), (this[t] = e)), this._updateTextarea();
							},
							_fireSelectionChanged: function () {
								this.fire('selection:changed'), this.canvas && this.canvas.fire('text:selection:changed', { target: this });
							},
							initDimensions: function () {
								this.isEditing && this.initDelayedCursor(), this.clearContextTop(), this.callSuper('initDimensions');
							},
							render: function (t) {
								this.clearContextTop(), this.callSuper('render', t), (this.cursorOffsetCache = {}), this.renderCursorOrSelection();
							},
							_render: function (t) {
								this.callSuper('_render', t);
							},
							clearContextTop: function (t) {
								if (this.isEditing && this.canvas && this.canvas.contextTop) {
									var e = this.canvas.contextTop,
										i = this.canvas.viewportTransform;
									e.save(), e.transform(i[0], i[1], i[2], i[3], i[4], i[5]), this.transform(e), this._clearTextArea(e), t || e.restore();
								}
							},
							renderCursorOrSelection: function () {
								if (this.isEditing && this.canvas && this.canvas.contextTop) {
									var t = this._getCursorBoundaries(),
										e = this.canvas.contextTop;
									this.clearContextTop(!0), this.selectionStart === this.selectionEnd ? this.renderCursor(t, e) : this.renderSelection(t, e), e.restore();
								}
							},
							_clearTextArea: function (t) {
								var e = this.width + 4,
									i = this.height + 4;
								t.clearRect(-e / 2, -i / 2, e, i);
							},
							_getCursorBoundaries: function (t) {
								'undefined' === typeof t && (t = this.selectionStart);
								var e = this._getLeftOffset(),
									i = this._getTopOffset(),
									n = this._getCursorBoundariesOffsets(t);
								return { left: e, top: i, leftOffset: n.left, topOffset: n.top };
							},
							_getCursorBoundariesOffsets: function (t) {
								if (this.cursorOffsetCache && 'top' in this.cursorOffsetCache) return this.cursorOffsetCache;
								var e,
									i,
									n,
									r,
									o = 0,
									s = 0,
									a = this.get2DCursorLocation(t);
								(n = a.charIndex), (i = a.lineIndex);
								for (var c = 0; c < i; c++) o += this.getHeightOfLine(c);
								e = this._getLineLeftOffset(i);
								var h = this.__charBounds[i][n];
								return (
									h && (s = h.left),
									0 !== this.charSpacing && n === this._textLines[i].length && (s -= this._getWidthOfCharSpacing()),
									(r = { top: o, left: e + (s > 0 ? s : 0) }),
									'rtl' === this.direction && (r.left *= -1),
									(this.cursorOffsetCache = r),
									this.cursorOffsetCache
								);
							},
							renderCursor: function (t, e) {
								var i = this.get2DCursorLocation(),
									n = i.lineIndex,
									r = i.charIndex > 0 ? i.charIndex - 1 : 0,
									o = this.getValueOfPropertyAt(n, r, 'fontSize'),
									s = this.scaleX * this.canvas.getZoom(),
									a = this.cursorWidth / s,
									c = t.topOffset,
									h = this.getValueOfPropertyAt(n, r, 'deltaY');
								(c += ((1 - this._fontSizeFraction) * this.getHeightOfLine(n)) / this.lineHeight - o * (1 - this._fontSizeFraction)),
									this.inCompositionMode && this.renderSelection(t, e),
									(e.fillStyle = this.cursorColor || this.getValueOfPropertyAt(n, r, 'fill')),
									(e.globalAlpha = this.__isMousedown ? 1 : this._currentCursorOpacity),
									e.fillRect(t.left + t.leftOffset - a / 2, c + t.top + h, a, o);
							},
							renderSelection: function (t, e) {
								for (
									var i = this.inCompositionMode ? this.hiddenTextarea.selectionStart : this.selectionStart,
										n = this.inCompositionMode ? this.hiddenTextarea.selectionEnd : this.selectionEnd,
										r = -1 !== this.textAlign.indexOf('justify'),
										o = this.get2DCursorLocation(i),
										s = this.get2DCursorLocation(n),
										a = o.lineIndex,
										c = s.lineIndex,
										h = o.charIndex < 0 ? 0 : o.charIndex,
										l = s.charIndex < 0 ? 0 : s.charIndex,
										u = a;
									u <= c;
									u++
								) {
									var f = this._getLineLeftOffset(u) || 0,
										d = this.getHeightOfLine(u),
										p = 0,
										g = 0,
										v = 0;
									if ((u === a && (g = this.__charBounds[a][h].left), u >= a && u < c)) v = r && !this.isEndOfWrapping(u) ? this.width : this.getLineWidth(u) || 5;
									else if (u === c)
										if (0 === l) v = this.__charBounds[c][l].left;
										else {
											var m = this._getWidthOfCharSpacing();
											v = this.__charBounds[c][l - 1].left + this.__charBounds[c][l - 1].width - m;
										}
									(p = d), (this.lineHeight < 1 || (u === c && this.lineHeight > 1)) && (d /= this.lineHeight);
									var y = t.left + f + g,
										b = v - g,
										x = d,
										_ = 0;
									this.inCompositionMode ? ((e.fillStyle = this.compositionColor || 'black'), (x = 1), (_ = d)) : (e.fillStyle = this.selectionColor),
										'rtl' === this.direction && (y = this.width - y - b),
										e.fillRect(y, t.top + t.topOffset + _, b, x),
										(t.topOffset += p);
								}
							},
							getCurrentCharFontSize: function () {
								var t = this._getCurrentCharIndex();
								return this.getValueOfPropertyAt(t.l, t.c, 'fontSize');
							},
							getCurrentCharColor: function () {
								var t = this._getCurrentCharIndex();
								return this.getValueOfPropertyAt(t.l, t.c, 'fill');
							},
							_getCurrentCharIndex: function () {
								var t = this.get2DCursorLocation(this.selectionStart, !0),
									e = t.charIndex > 0 ? t.charIndex - 1 : 0;
								return { l: t.lineIndex, c: e };
							}
						})),
							(n.IText.fromObject = function (e, i) {
								if (((e.styles = n.util.stylesFromArray(e.styles, e.text)), t(e), e.styles)) for (var r in e.styles) for (var o in e.styles[r]) t(e.styles[r][o]);
								n.Object._fromObject('IText', e, i, 'text');
							});
					})(),
					(function () {
						var t = n.util.object.clone;
						n.util.object.extend(n.IText.prototype, {
							initBehavior: function () {
								this.initAddedHandler(),
									this.initRemovedHandler(),
									this.initCursorSelectionHandlers(),
									this.initDoubleClickSimulation(),
									(this.mouseMoveHandler = this.mouseMoveHandler.bind(this));
							},
							onDeselect: function () {
								this.isEditing && this.exitEditing(), (this.selected = !1);
							},
							initAddedHandler: function () {
								var t = this;
								this.on('added', function () {
									var e = t.canvas;
									e && (e._hasITextHandlers || ((e._hasITextHandlers = !0), t._initCanvasHandlers(e)), (e._iTextInstances = e._iTextInstances || []), e._iTextInstances.push(t));
								});
							},
							initRemovedHandler: function () {
								var t = this;
								this.on('removed', function () {
									var e = t.canvas;
									e &&
										((e._iTextInstances = e._iTextInstances || []),
										n.util.removeFromArray(e._iTextInstances, t),
										0 === e._iTextInstances.length && ((e._hasITextHandlers = !1), t._removeCanvasHandlers(e)));
								});
							},
							_initCanvasHandlers: function (t) {
								(t._mouseUpITextHandler = function () {
									t._iTextInstances &&
										t._iTextInstances.forEach(function (t) {
											t.__isMousedown = !1;
										});
								}),
									t.on('mouse:up', t._mouseUpITextHandler);
							},
							_removeCanvasHandlers: function (t) {
								t.off('mouse:up', t._mouseUpITextHandler);
							},
							_tick: function () {
								this._currentTickState = this._animateCursor(this, 1, this.cursorDuration, '_onTickComplete');
							},
							_animateCursor: function (t, e, i, n) {
								var r;
								return (
									(r = {
										isAborted: !1,
										abort: function () {
											this.isAborted = !0;
										}
									}),
									t.animate('_currentCursorOpacity', e, {
										duration: i,
										onComplete: function () {
											r.isAborted || t[n]();
										},
										onChange: function () {
											t.canvas && t.selectionStart === t.selectionEnd && t.renderCursorOrSelection();
										},
										abort: function () {
											return r.isAborted;
										}
									}),
									r
								);
							},
							_onTickComplete: function () {
								var t = this;
								this._cursorTimeout1 && clearTimeout(this._cursorTimeout1),
									(this._cursorTimeout1 = setTimeout(function () {
										t._currentTickCompleteState = t._animateCursor(t, 0, this.cursorDuration / 2, '_tick');
									}, 100));
							},
							initDelayedCursor: function (t) {
								var e = this,
									i = t ? 0 : this.cursorDelay;
								this.abortCursorAnimation(),
									(this._currentCursorOpacity = 1),
									(this._cursorTimeout2 = setTimeout(function () {
										e._tick();
									}, i));
							},
							abortCursorAnimation: function () {
								var t = this._currentTickState || this._currentTickCompleteState,
									e = this.canvas;
								this._currentTickState && this._currentTickState.abort(),
									this._currentTickCompleteState && this._currentTickCompleteState.abort(),
									clearTimeout(this._cursorTimeout1),
									clearTimeout(this._cursorTimeout2),
									(this._currentCursorOpacity = 0),
									t && e && e.clearContext(e.contextTop || e.contextContainer);
							},
							selectAll: function () {
								return (this.selectionStart = 0), (this.selectionEnd = this._text.length), this._fireSelectionChanged(), this._updateTextarea(), this;
							},
							getSelectedText: function () {
								return this._text.slice(this.selectionStart, this.selectionEnd).join('');
							},
							findWordBoundaryLeft: function (t) {
								var e = 0,
									i = t - 1;
								if (this._reSpace.test(this._text[i])) while (this._reSpace.test(this._text[i])) e++, i--;
								while (/\S/.test(this._text[i]) && i > -1) e++, i--;
								return t - e;
							},
							findWordBoundaryRight: function (t) {
								var e = 0,
									i = t;
								if (this._reSpace.test(this._text[i])) while (this._reSpace.test(this._text[i])) e++, i++;
								while (/\S/.test(this._text[i]) && i < this._text.length) e++, i++;
								return t + e;
							},
							findLineBoundaryLeft: function (t) {
								var e = 0,
									i = t - 1;
								while (!/\n/.test(this._text[i]) && i > -1) e++, i--;
								return t - e;
							},
							findLineBoundaryRight: function (t) {
								var e = 0,
									i = t;
								while (!/\n/.test(this._text[i]) && i < this._text.length) e++, i++;
								return t + e;
							},
							searchWordBoundary: function (t, e) {
								var i = this._text,
									r = this._reSpace.test(i[t]) ? t - 1 : t,
									o = i[r],
									s = n.reNonWord;
								while (!s.test(o) && r > 0 && r < i.length) (r += e), (o = i[r]);
								return s.test(o) && (r += 1 === e ? 0 : 1), r;
							},
							selectWord: function (t) {
								t = t || this.selectionStart;
								var e = this.searchWordBoundary(t, -1),
									i = this.searchWordBoundary(t, 1);
								(this.selectionStart = e), (this.selectionEnd = i), this._fireSelectionChanged(), this._updateTextarea(), this.renderCursorOrSelection();
							},
							selectLine: function (t) {
								t = t || this.selectionStart;
								var e = this.findLineBoundaryLeft(t),
									i = this.findLineBoundaryRight(t);
								return (this.selectionStart = e), (this.selectionEnd = i), this._fireSelectionChanged(), this._updateTextarea(), this;
							},
							enterEditing: function (t) {
								if (!this.isEditing && this.editable)
									return (
										this.canvas && (this.canvas.calcOffset(), this.exitEditingOnOthers(this.canvas)),
										(this.isEditing = !0),
										this.initHiddenTextarea(t),
										this.hiddenTextarea.focus(),
										(this.hiddenTextarea.value = this.text),
										this._updateTextarea(),
										this._saveEditingProps(),
										this._setEditingProps(),
										(this._textBeforeEdit = this.text),
										this._tick(),
										this.fire('editing:entered'),
										this._fireSelectionChanged(),
										this.canvas ? (this.canvas.fire('text:editing:entered', { target: this }), this.initMouseMoveHandler(), this.canvas.requestRenderAll(), this) : this
									);
							},
							exitEditingOnOthers: function (t) {
								t._iTextInstances &&
									t._iTextInstances.forEach(function (t) {
										(t.selected = !1), t.isEditing && t.exitEditing();
									});
							},
							initMouseMoveHandler: function () {
								this.canvas.on('mouse:move', this.mouseMoveHandler);
							},
							mouseMoveHandler: function (t) {
								if (this.__isMousedown && this.isEditing) {
									var e = this.getSelectionStartFromPointer(t.e),
										i = this.selectionStart,
										n = this.selectionEnd;
									((e === this.__selectionStartOnMouseDown && i !== n) || (i !== e && n !== e)) &&
										(e > this.__selectionStartOnMouseDown
											? ((this.selectionStart = this.__selectionStartOnMouseDown), (this.selectionEnd = e))
											: ((this.selectionStart = e), (this.selectionEnd = this.__selectionStartOnMouseDown)),
										(this.selectionStart === i && this.selectionEnd === n) ||
											(this.restartCursorIfNeeded(), this._fireSelectionChanged(), this._updateTextarea(), this.renderCursorOrSelection()));
								}
							},
							_setEditingProps: function () {
								(this.hoverCursor = 'text'),
									this.canvas && (this.canvas.defaultCursor = this.canvas.moveCursor = 'text'),
									(this.borderColor = this.editingBorderColor),
									(this.hasControls = this.selectable = !1),
									(this.lockMovementX = this.lockMovementY = !0);
							},
							fromStringToGraphemeSelection: function (t, e, i) {
								var r = i.slice(0, t),
									o = n.util.string.graphemeSplit(r).length;
								if (t === e) return { selectionStart: o, selectionEnd: o };
								var s = i.slice(t, e),
									a = n.util.string.graphemeSplit(s).length;
								return { selectionStart: o, selectionEnd: o + a };
							},
							fromGraphemeToStringSelection: function (t, e, i) {
								var n = i.slice(0, t),
									r = n.join('').length;
								if (t === e) return { selectionStart: r, selectionEnd: r };
								var o = i.slice(t, e),
									s = o.join('').length;
								return { selectionStart: r, selectionEnd: r + s };
							},
							_updateTextarea: function () {
								if (((this.cursorOffsetCache = {}), this.hiddenTextarea)) {
									if (!this.inCompositionMode) {
										var t = this.fromGraphemeToStringSelection(this.selectionStart, this.selectionEnd, this._text);
										(this.hiddenTextarea.selectionStart = t.selectionStart), (this.hiddenTextarea.selectionEnd = t.selectionEnd);
									}
									this.updateTextareaPosition();
								}
							},
							updateFromTextArea: function () {
								if (this.hiddenTextarea) {
									(this.cursorOffsetCache = {}), (this.text = this.hiddenTextarea.value), this._shouldClearDimensionCache() && (this.initDimensions(), this.setCoords());
									var t = this.fromStringToGraphemeSelection(this.hiddenTextarea.selectionStart, this.hiddenTextarea.selectionEnd, this.hiddenTextarea.value);
									(this.selectionEnd = this.selectionStart = t.selectionEnd), this.inCompositionMode || (this.selectionStart = t.selectionStart), this.updateTextareaPosition();
								}
							},
							updateTextareaPosition: function () {
								if (this.selectionStart === this.selectionEnd) {
									var t = this._calcTextareaPosition();
									(this.hiddenTextarea.style.left = t.left), (this.hiddenTextarea.style.top = t.top);
								}
							},
							_calcTextareaPosition: function () {
								if (!this.canvas) return { x: 1, y: 1 };
								var t = this.inCompositionMode ? this.compositionStart : this.selectionStart,
									e = this._getCursorBoundaries(t),
									i = this.get2DCursorLocation(t),
									r = i.lineIndex,
									o = i.charIndex,
									s = this.getValueOfPropertyAt(r, o, 'fontSize') * this.lineHeight,
									a = e.leftOffset,
									c = this.calcTransformMatrix(),
									h = { x: e.left + a, y: e.top + e.topOffset + s },
									l = this.canvas.getRetinaScaling(),
									u = this.canvas.upperCanvasEl,
									f = u.width / l,
									d = u.height / l,
									p = f - s,
									g = d - s,
									v = u.clientWidth / f,
									m = u.clientHeight / d;
								return (
									(h = n.util.transformPoint(h, c)),
									(h = n.util.transformPoint(h, this.canvas.viewportTransform)),
									(h.x *= v),
									(h.y *= m),
									h.x < 0 && (h.x = 0),
									h.x > p && (h.x = p),
									h.y < 0 && (h.y = 0),
									h.y > g && (h.y = g),
									(h.x += this.canvas._offset.left),
									(h.y += this.canvas._offset.top),
									{ left: h.x + 'px', top: h.y + 'px', fontSize: s + 'px', charHeight: s }
								);
							},
							_saveEditingProps: function () {
								this._savedProps = {
									hasControls: this.hasControls,
									borderColor: this.borderColor,
									lockMovementX: this.lockMovementX,
									lockMovementY: this.lockMovementY,
									hoverCursor: this.hoverCursor,
									selectable: this.selectable,
									defaultCursor: this.canvas && this.canvas.defaultCursor,
									moveCursor: this.canvas && this.canvas.moveCursor
								};
							},
							_restoreEditingProps: function () {
								this._savedProps &&
									((this.hoverCursor = this._savedProps.hoverCursor),
									(this.hasControls = this._savedProps.hasControls),
									(this.borderColor = this._savedProps.borderColor),
									(this.selectable = this._savedProps.selectable),
									(this.lockMovementX = this._savedProps.lockMovementX),
									(this.lockMovementY = this._savedProps.lockMovementY),
									this.canvas && ((this.canvas.defaultCursor = this._savedProps.defaultCursor), (this.canvas.moveCursor = this._savedProps.moveCursor)));
							},
							exitEditing: function () {
								var t = this._textBeforeEdit !== this.text,
									e = this.hiddenTextarea;
								return (
									(this.selected = !1),
									(this.isEditing = !1),
									(this.selectionEnd = this.selectionStart),
									e && (e.blur && e.blur(), e.parentNode && e.parentNode.removeChild(e)),
									(this.hiddenTextarea = null),
									this.abortCursorAnimation(),
									this._restoreEditingProps(),
									(this._currentCursorOpacity = 0),
									this._shouldClearDimensionCache() && (this.initDimensions(), this.setCoords()),
									this.fire('editing:exited'),
									t && this.fire('modified'),
									this.canvas &&
										(this.canvas.off('mouse:move', this.mouseMoveHandler),
										this.canvas.fire('text:editing:exited', { target: this }),
										t && this.canvas.fire('object:modified', { target: this })),
									this
								);
							},
							_removeExtraneousStyles: function () {
								for (var t in this.styles) this._textLines[t] || delete this.styles[t];
							},
							removeStyleFromTo: function (t, e) {
								var i,
									n,
									r = this.get2DCursorLocation(t, !0),
									o = this.get2DCursorLocation(e, !0),
									s = r.lineIndex,
									a = r.charIndex,
									c = o.lineIndex,
									h = o.charIndex;
								if (s !== c) {
									if (this.styles[s]) for (i = a; i < this._unwrappedTextLines[s].length; i++) delete this.styles[s][i];
									if (this.styles[c])
										for (i = h; i < this._unwrappedTextLines[c].length; i++)
											(n = this.styles[c][i]), n && (this.styles[s] || (this.styles[s] = {}), (this.styles[s][a + i - h] = n));
									for (i = s + 1; i <= c; i++) delete this.styles[i];
									this.shiftLineStyles(c, s - c);
								} else if (this.styles[s]) {
									n = this.styles[s];
									var l,
										u,
										f = h - a;
									for (i = a; i < h; i++) delete n[i];
									for (u in this.styles[s]) (l = parseInt(u, 10)), l >= h && ((n[l - f] = n[u]), delete n[u]);
								}
							},
							shiftLineStyles: function (e, i) {
								var n = t(this.styles);
								for (var r in this.styles) {
									var o = parseInt(r, 10);
									o > e && ((this.styles[o + i] = n[o]), n[o - i] || delete this.styles[o]);
								}
							},
							restartCursorIfNeeded: function () {
								(this._currentTickState && !this._currentTickState.isAborted && this._currentTickCompleteState && !this._currentTickCompleteState.isAborted) ||
									this.initDelayedCursor();
							},
							insertNewlineStyleObject: function (e, i, n, r) {
								var o,
									s = {},
									a = !1,
									c = this._unwrappedTextLines[e].length === i;
								for (var h in (n || (n = 1), this.shiftLineStyles(e, n), this.styles[e] && (o = this.styles[e][0 === i ? i : i - 1]), this.styles[e])) {
									var l = parseInt(h, 10);
									l >= i && ((a = !0), (s[l - i] = this.styles[e][h]), (c && 0 === i) || delete this.styles[e][h]);
								}
								var u = !1;
								a && !c && ((this.styles[e + n] = s), (u = !0)), u && n--;
								while (n > 0) r && r[n - 1] ? (this.styles[e + n] = { 0: t(r[n - 1]) }) : o ? (this.styles[e + n] = { 0: t(o) }) : delete this.styles[e + n], n--;
								this._forceClearCache = !0;
							},
							insertCharStyleObject: function (e, i, n, r) {
								this.styles || (this.styles = {});
								var o = this.styles[e],
									s = o ? t(o) : {};
								for (var a in (n || (n = 1), s)) {
									var c = parseInt(a, 10);
									c >= i && ((o[c + n] = s[c]), s[c - n] || delete o[c]);
								}
								if (((this._forceClearCache = !0), r)) while (n--) Object.keys(r[n]).length && (this.styles[e] || (this.styles[e] = {}), (this.styles[e][i + n] = t(r[n])));
								else if (o) {
									var h = o[i ? i - 1 : 1];
									while (h && n--) this.styles[e][i + n] = t(h);
								}
							},
							insertNewStyleBlock: function (t, e, i) {
								for (var n = this.get2DCursorLocation(e, !0), r = [0], o = 0, s = 0; s < t.length; s++) '\n' === t[s] ? (o++, (r[o] = 0)) : r[o]++;
								r[0] > 0 && (this.insertCharStyleObject(n.lineIndex, n.charIndex, r[0], i), (i = i && i.slice(r[0] + 1))),
									o && this.insertNewlineStyleObject(n.lineIndex, n.charIndex + r[0], o);
								for (s = 1; s < o; s++)
									r[s] > 0 ? this.insertCharStyleObject(n.lineIndex + s, 0, r[s], i) : i && this.styles[n.lineIndex + s] && i[0] && (this.styles[n.lineIndex + s][0] = i[0]),
										(i = i && i.slice(r[s] + 1));
								r[s] > 0 && this.insertCharStyleObject(n.lineIndex + s, 0, r[s], i);
							},
							setSelectionStartEndWithShift: function (t, e, i) {
								i <= t
									? (e === t ? (this._selectionDirection = 'left') : 'right' === this._selectionDirection && ((this._selectionDirection = 'left'), (this.selectionEnd = t)),
									  (this.selectionStart = i))
									: i > t && i < e
									? 'right' === this._selectionDirection
										? (this.selectionEnd = i)
										: (this.selectionStart = i)
									: (e === t ? (this._selectionDirection = 'right') : 'left' === this._selectionDirection && ((this._selectionDirection = 'right'), (this.selectionStart = e)),
									  (this.selectionEnd = i));
							},
							setSelectionInBoundaries: function () {
								var t = this.text.length;
								this.selectionStart > t ? (this.selectionStart = t) : this.selectionStart < 0 && (this.selectionStart = 0),
									this.selectionEnd > t ? (this.selectionEnd = t) : this.selectionEnd < 0 && (this.selectionEnd = 0);
							}
						});
					})(),
					n.util.object.extend(n.IText.prototype, {
						initDoubleClickSimulation: function () {
							(this.__lastClickTime = +new Date()), (this.__lastLastClickTime = +new Date()), (this.__lastPointer = {}), this.on('mousedown', this.onMouseDown);
						},
						onMouseDown: function (t) {
							if (this.canvas) {
								this.__newClickTime = +new Date();
								var e = t.pointer;
								this.isTripleClick(e) && (this.fire('tripleclick', t), this._stopEvent(t.e)),
									(this.__lastLastClickTime = this.__lastClickTime),
									(this.__lastClickTime = this.__newClickTime),
									(this.__lastPointer = e),
									(this.__lastIsEditing = this.isEditing),
									(this.__lastSelected = this.selected);
							}
						},
						isTripleClick: function (t) {
							return (
								this.__newClickTime - this.__lastClickTime < 500 &&
								this.__lastClickTime - this.__lastLastClickTime < 500 &&
								this.__lastPointer.x === t.x &&
								this.__lastPointer.y === t.y
							);
						},
						_stopEvent: function (t) {
							t.preventDefault && t.preventDefault(), t.stopPropagation && t.stopPropagation();
						},
						initCursorSelectionHandlers: function () {
							this.initMousedownHandler(), this.initMouseupHandler(), this.initClicks();
						},
						doubleClickHandler: function (t) {
							this.isEditing && this.selectWord(this.getSelectionStartFromPointer(t.e));
						},
						tripleClickHandler: function (t) {
							this.isEditing && this.selectLine(this.getSelectionStartFromPointer(t.e));
						},
						initClicks: function () {
							this.on('mousedblclick', this.doubleClickHandler), this.on('tripleclick', this.tripleClickHandler);
						},
						_mouseDownHandler: function (t) {
							!this.canvas ||
								!this.editable ||
								(t.e.button && 1 !== t.e.button) ||
								((this.__isMousedown = !0),
								this.selected && ((this.inCompositionMode = !1), this.setCursorByClick(t.e)),
								this.isEditing &&
									((this.__selectionStartOnMouseDown = this.selectionStart),
									this.selectionStart === this.selectionEnd && this.abortCursorAnimation(),
									this.renderCursorOrSelection()));
						},
						_mouseDownHandlerBefore: function (t) {
							!this.canvas || !this.editable || (t.e.button && 1 !== t.e.button) || (this.selected = this === this.canvas._activeObject);
						},
						initMousedownHandler: function () {
							this.on('mousedown', this._mouseDownHandler), this.on('mousedown:before', this._mouseDownHandlerBefore);
						},
						initMouseupHandler: function () {
							this.on('mouseup', this.mouseUpHandler);
						},
						mouseUpHandler: function (t) {
							if (((this.__isMousedown = !1), !(!this.editable || this.group || (t.transform && t.transform.actionPerformed) || (t.e.button && 1 !== t.e.button)))) {
								if (this.canvas) {
									var e = this.canvas._activeObject;
									if (e && e !== this) return;
								}
								this.__lastSelected && !this.__corner
									? ((this.selected = !1),
									  (this.__lastSelected = !1),
									  this.enterEditing(t.e),
									  this.selectionStart === this.selectionEnd ? this.initDelayedCursor(!0) : this.renderCursorOrSelection())
									: (this.selected = !0);
							}
						},
						setCursorByClick: function (t) {
							var e = this.getSelectionStartFromPointer(t),
								i = this.selectionStart,
								n = this.selectionEnd;
							t.shiftKey ? this.setSelectionStartEndWithShift(i, n, e) : ((this.selectionStart = e), (this.selectionEnd = e)),
								this.isEditing && (this._fireSelectionChanged(), this._updateTextarea());
						},
						getSelectionStartFromPointer: function (t) {
							for (var e, i, n = this.getLocalPointer(t), r = 0, o = 0, s = 0, a = 0, c = 0, h = 0, l = this._textLines.length; h < l; h++) {
								if (!(s <= n.y)) break;
								(s += this.getHeightOfLine(h) * this.scaleY), (c = h), h > 0 && (a += this._textLines[h - 1].length + this.missingNewlineOffset(h - 1));
							}
							(e = this._getLineLeftOffset(c)), (o = e * this.scaleX), (i = this._textLines[c]), 'rtl' === this.direction && (n.x = this.width * this.scaleX - n.x + o);
							for (var u = 0, f = i.length; u < f; u++) {
								if (((r = o), (o += this.__charBounds[c][u].kernedWidth * this.scaleX), !(o <= n.x))) break;
								a++;
							}
							return this._getNewSelectionStartFromOffset(n, r, o, a, f);
						},
						_getNewSelectionStartFromOffset: function (t, e, i, n, r) {
							var o = t.x - e,
								s = i - t.x,
								a = s > o || s < 0 ? 0 : 1,
								c = n + a;
							return this.flipX && (c = r - c), c > this._text.length && (c = this._text.length), c;
						}
					}),
					n.util.object.extend(n.IText.prototype, {
						initHiddenTextarea: function () {
							(this.hiddenTextarea = n.document.createElement('textarea')),
								this.hiddenTextarea.setAttribute('autocapitalize', 'off'),
								this.hiddenTextarea.setAttribute('autocorrect', 'off'),
								this.hiddenTextarea.setAttribute('autocomplete', 'off'),
								this.hiddenTextarea.setAttribute('spellcheck', 'false'),
								this.hiddenTextarea.setAttribute('data-fabric-hiddentextarea', ''),
								this.hiddenTextarea.setAttribute('wrap', 'off');
							var t = this._calcTextareaPosition();
							(this.hiddenTextarea.style.cssText =
								'position: absolute; top: ' + t.top + '; left: ' + t.left + '; z-index: -999; opacity: 0; width: 1px; height: 1px; font-size: 1px; paddingｰtop: ' + t.fontSize + ';'),
								this.hiddenTextareaContainer ? this.hiddenTextareaContainer.appendChild(this.hiddenTextarea) : n.document.body.appendChild(this.hiddenTextarea),
								n.util.addListener(this.hiddenTextarea, 'keydown', this.onKeyDown.bind(this)),
								n.util.addListener(this.hiddenTextarea, 'keyup', this.onKeyUp.bind(this)),
								n.util.addListener(this.hiddenTextarea, 'input', this.onInput.bind(this)),
								n.util.addListener(this.hiddenTextarea, 'copy', this.copy.bind(this)),
								n.util.addListener(this.hiddenTextarea, 'cut', this.copy.bind(this)),
								n.util.addListener(this.hiddenTextarea, 'paste', this.paste.bind(this)),
								n.util.addListener(this.hiddenTextarea, 'compositionstart', this.onCompositionStart.bind(this)),
								n.util.addListener(this.hiddenTextarea, 'compositionupdate', this.onCompositionUpdate.bind(this)),
								n.util.addListener(this.hiddenTextarea, 'compositionend', this.onCompositionEnd.bind(this)),
								!this._clickHandlerInitialized &&
									this.canvas &&
									(n.util.addListener(this.canvas.upperCanvasEl, 'click', this.onClick.bind(this)), (this._clickHandlerInitialized = !0));
						},
						keysMap: {
							9: 'exitEditing',
							27: 'exitEditing',
							33: 'moveCursorUp',
							34: 'moveCursorDown',
							35: 'moveCursorRight',
							36: 'moveCursorLeft',
							37: 'moveCursorLeft',
							38: 'moveCursorUp',
							39: 'moveCursorRight',
							40: 'moveCursorDown'
						},
						keysMapRtl: {
							9: 'exitEditing',
							27: 'exitEditing',
							33: 'moveCursorUp',
							34: 'moveCursorDown',
							35: 'moveCursorLeft',
							36: 'moveCursorRight',
							37: 'moveCursorRight',
							38: 'moveCursorUp',
							39: 'moveCursorLeft',
							40: 'moveCursorDown'
						},
						ctrlKeysMapUp: { 67: 'copy', 88: 'cut' },
						ctrlKeysMapDown: { 65: 'selectAll' },
						onClick: function () {
							this.hiddenTextarea && this.hiddenTextarea.focus();
						},
						onKeyDown: function (t) {
							if (this.isEditing) {
								var e = 'rtl' === this.direction ? this.keysMapRtl : this.keysMap;
								if (t.keyCode in e) this[e[t.keyCode]](t);
								else {
									if (!(t.keyCode in this.ctrlKeysMapDown) || (!t.ctrlKey && !t.metaKey)) return;
									this[this.ctrlKeysMapDown[t.keyCode]](t);
								}
								t.stopImmediatePropagation(),
									t.preventDefault(),
									t.keyCode >= 33 && t.keyCode <= 40
										? ((this.inCompositionMode = !1), this.clearContextTop(), this.renderCursorOrSelection())
										: this.canvas && this.canvas.requestRenderAll();
							}
						},
						onKeyUp: function (t) {
							!this.isEditing || this._copyDone || this.inCompositionMode
								? (this._copyDone = !1)
								: t.keyCode in this.ctrlKeysMapUp &&
								  (t.ctrlKey || t.metaKey) &&
								  (this[this.ctrlKeysMapUp[t.keyCode]](t), t.stopImmediatePropagation(), t.preventDefault(), this.canvas && this.canvas.requestRenderAll());
						},
						onInput: function (t) {
							var e = this.fromPaste;
							if (((this.fromPaste = !1), t && t.stopPropagation(), this.isEditing)) {
								var i,
									r,
									o,
									s,
									a,
									c = this._splitTextIntoLines(this.hiddenTextarea.value).graphemeText,
									h = this._text.length,
									l = c.length,
									u = l - h,
									f = this.selectionStart,
									d = this.selectionEnd,
									p = f !== d;
								if ('' === this.hiddenTextarea.value)
									return (
										(this.styles = {}),
										this.updateFromTextArea(),
										this.fire('changed'),
										void (this.canvas && (this.canvas.fire('text:changed', { target: this }), this.canvas.requestRenderAll()))
									);
								var g = this.fromStringToGraphemeSelection(this.hiddenTextarea.selectionStart, this.hiddenTextarea.selectionEnd, this.hiddenTextarea.value),
									v = f > g.selectionStart;
								p ? ((i = this._text.slice(f, d)), (u += d - f)) : l < h && (i = v ? this._text.slice(d + u, d) : this._text.slice(f, f - u)),
									(r = c.slice(g.selectionEnd - u, g.selectionEnd)),
									i &&
										i.length &&
										(r.length &&
											((o = this.getSelectionStyles(f, f + 1, !1)),
											(o = r.map(function () {
												return o[0];
											}))),
										p ? ((s = f), (a = d)) : v ? ((s = d - i.length), (a = d)) : ((s = d), (a = d + i.length)),
										this.removeStyleFromTo(s, a)),
									r.length && (e && r.join('') === n.copiedText && !n.disableStyleCopyPaste && (o = n.copiedTextStyle), this.insertNewStyleBlock(r, f, o)),
									this.updateFromTextArea(),
									this.fire('changed'),
									this.canvas && (this.canvas.fire('text:changed', { target: this }), this.canvas.requestRenderAll());
							}
						},
						onCompositionStart: function () {
							this.inCompositionMode = !0;
						},
						onCompositionEnd: function () {
							this.inCompositionMode = !1;
						},
						onCompositionUpdate: function (t) {
							(this.compositionStart = t.target.selectionStart), (this.compositionEnd = t.target.selectionEnd), this.updateTextareaPosition();
						},
						copy: function () {
							this.selectionStart !== this.selectionEnd &&
								((n.copiedText = this.getSelectedText()),
								n.disableStyleCopyPaste ? (n.copiedTextStyle = null) : (n.copiedTextStyle = this.getSelectionStyles(this.selectionStart, this.selectionEnd, !0)),
								(this._copyDone = !0));
						},
						paste: function () {
							this.fromPaste = !0;
						},
						_getClipboardData: function (t) {
							return (t && t.clipboardData) || n.window.clipboardData;
						},
						_getWidthBeforeCursor: function (t, e) {
							var i,
								n = this._getLineLeftOffset(t);
							return e > 0 && ((i = this.__charBounds[t][e - 1]), (n += i.left + i.width)), n;
						},
						getDownCursorOffset: function (t, e) {
							var i = this._getSelectionForOffset(t, e),
								n = this.get2DCursorLocation(i),
								r = n.lineIndex;
							if (r === this._textLines.length - 1 || t.metaKey || 34 === t.keyCode) return this._text.length - i;
							var o = n.charIndex,
								s = this._getWidthBeforeCursor(r, o),
								a = this._getIndexOnLine(r + 1, s),
								c = this._textLines[r].slice(o);
							return c.length + a + 1 + this.missingNewlineOffset(r);
						},
						_getSelectionForOffset: function (t, e) {
							return t.shiftKey && this.selectionStart !== this.selectionEnd && e ? this.selectionEnd : this.selectionStart;
						},
						getUpCursorOffset: function (t, e) {
							var i = this._getSelectionForOffset(t, e),
								n = this.get2DCursorLocation(i),
								r = n.lineIndex;
							if (0 === r || t.metaKey || 33 === t.keyCode) return -i;
							var o = n.charIndex,
								s = this._getWidthBeforeCursor(r, o),
								a = this._getIndexOnLine(r - 1, s),
								c = this._textLines[r].slice(0, o),
								h = this.missingNewlineOffset(r - 1);
							return -this._textLines[r - 1].length + a - c.length + (1 - h);
						},
						_getIndexOnLine: function (t, e) {
							for (var i, n, r = this._textLines[t], o = this._getLineLeftOffset(t), s = o, a = 0, c = 0, h = r.length; c < h; c++)
								if (((i = this.__charBounds[t][c].width), (s += i), s > e)) {
									n = !0;
									var l = s - i,
										u = s,
										f = Math.abs(l - e),
										d = Math.abs(u - e);
									a = d < f ? c : c - 1;
									break;
								}
							return n || (a = r.length - 1), a;
						},
						moveCursorDown: function (t) {
							(this.selectionStart >= this._text.length && this.selectionEnd >= this._text.length) || this._moveCursorUpOrDown('Down', t);
						},
						moveCursorUp: function (t) {
							(0 === this.selectionStart && 0 === this.selectionEnd) || this._moveCursorUpOrDown('Up', t);
						},
						_moveCursorUpOrDown: function (t, e) {
							var i = 'get' + t + 'CursorOffset',
								n = this[i](e, 'right' === this._selectionDirection);
							e.shiftKey ? this.moveCursorWithShift(n) : this.moveCursorWithoutShift(n),
								0 !== n &&
									(this.setSelectionInBoundaries(),
									this.abortCursorAnimation(),
									(this._currentCursorOpacity = 1),
									this.initDelayedCursor(),
									this._fireSelectionChanged(),
									this._updateTextarea());
						},
						moveCursorWithShift: function (t) {
							var e = 'left' === this._selectionDirection ? this.selectionStart + t : this.selectionEnd + t;
							return this.setSelectionStartEndWithShift(this.selectionStart, this.selectionEnd, e), 0 !== t;
						},
						moveCursorWithoutShift: function (t) {
							return t < 0 ? ((this.selectionStart += t), (this.selectionEnd = this.selectionStart)) : ((this.selectionEnd += t), (this.selectionStart = this.selectionEnd)), 0 !== t;
						},
						moveCursorLeft: function (t) {
							(0 === this.selectionStart && 0 === this.selectionEnd) || this._moveCursorLeftOrRight('Left', t);
						},
						_move: function (t, e, i) {
							var n;
							if (t.altKey) n = this['findWordBoundary' + i](this[e]);
							else {
								if (!t.metaKey && 35 !== t.keyCode && 36 !== t.keyCode) return (this[e] += 'Left' === i ? -1 : 1), !0;
								n = this['findLineBoundary' + i](this[e]);
							}
							if (void 0 !== typeof n && this[e] !== n) return (this[e] = n), !0;
						},
						_moveLeft: function (t, e) {
							return this._move(t, e, 'Left');
						},
						_moveRight: function (t, e) {
							return this._move(t, e, 'Right');
						},
						moveCursorLeftWithoutShift: function (t) {
							var e = !0;
							return (
								(this._selectionDirection = 'left'),
								this.selectionEnd === this.selectionStart && 0 !== this.selectionStart && (e = this._moveLeft(t, 'selectionStart')),
								(this.selectionEnd = this.selectionStart),
								e
							);
						},
						moveCursorLeftWithShift: function (t) {
							return 'right' === this._selectionDirection && this.selectionStart !== this.selectionEnd
								? this._moveLeft(t, 'selectionEnd')
								: 0 !== this.selectionStart
								? ((this._selectionDirection = 'left'), this._moveLeft(t, 'selectionStart'))
								: void 0;
						},
						moveCursorRight: function (t) {
							(this.selectionStart >= this._text.length && this.selectionEnd >= this._text.length) || this._moveCursorLeftOrRight('Right', t);
						},
						_moveCursorLeftOrRight: function (t, e) {
							var i = 'moveCursor' + t + 'With';
							(this._currentCursorOpacity = 1),
								e.shiftKey ? (i += 'Shift') : (i += 'outShift'),
								this[i](e) && (this.abortCursorAnimation(), this.initDelayedCursor(), this._fireSelectionChanged(), this._updateTextarea());
						},
						moveCursorRightWithShift: function (t) {
							return 'left' === this._selectionDirection && this.selectionStart !== this.selectionEnd
								? this._moveRight(t, 'selectionStart')
								: this.selectionEnd !== this._text.length
								? ((this._selectionDirection = 'right'), this._moveRight(t, 'selectionEnd'))
								: void 0;
						},
						moveCursorRightWithoutShift: function (t) {
							var e = !0;
							return (
								(this._selectionDirection = 'right'),
								this.selectionStart === this.selectionEnd
									? ((e = this._moveRight(t, 'selectionStart')), (this.selectionEnd = this.selectionStart))
									: (this.selectionStart = this.selectionEnd),
								e
							);
						},
						removeChars: function (t, e) {
							'undefined' === typeof e && (e = t + 1),
								this.removeStyleFromTo(t, e),
								this._text.splice(t, e - t),
								(this.text = this._text.join('')),
								this.set('dirty', !0),
								this._shouldClearDimensionCache() && (this.initDimensions(), this.setCoords()),
								this._removeExtraneousStyles();
						},
						insertChars: function (t, e, i, r) {
							'undefined' === typeof r && (r = i), r > i && this.removeStyleFromTo(i, r);
							var o = n.util.string.graphemeSplit(t);
							this.insertNewStyleBlock(o, i, e),
								(this._text = [].concat(this._text.slice(0, i), o, this._text.slice(r))),
								(this.text = this._text.join('')),
								this.set('dirty', !0),
								this._shouldClearDimensionCache() && (this.initDimensions(), this.setCoords()),
								this._removeExtraneousStyles();
						}
					}),
					(function () {
						var t = n.util.toFixed,
							e = /  +/g;
						n.util.object.extend(n.Text.prototype, {
							_toSVG: function () {
								var t = this._getSVGLeftTopOffsets(),
									e = this._getSVGTextAndBg(t.textTop, t.textLeft);
								return this._wrapSVGTextAndBg(e);
							},
							toSVG: function (t) {
								return this._createBaseSVGMarkup(this._toSVG(), { reviver: t, noStyle: !0, withShadow: !0 });
							},
							_getSVGLeftTopOffsets: function () {
								return { textLeft: -this.width / 2, textTop: -this.height / 2, lineTop: this.getHeightOfLine(0) };
							},
							_wrapSVGTextAndBg: function (t) {
								var e = !0,
									i = this.getSvgTextDecoration(this);
								return [
									t.textBgRects.join(''),
									'\t\t<text xml:space="preserve" ',
									this.fontFamily ? 'font-family="' + this.fontFamily.replace(/"/g, "'") + '" ' : '',
									this.fontSize ? 'font-size="' + this.fontSize + '" ' : '',
									this.fontStyle ? 'font-style="' + this.fontStyle + '" ' : '',
									this.fontWeight ? 'font-weight="' + this.fontWeight + '" ' : '',
									i ? 'text-decoration="' + i + '" ' : '',
									'style="',
									this.getSvgStyles(e),
									'"',
									this.addPaintOrder(),
									' >',
									t.textSpans.join(''),
									'</text>\n'
								];
							},
							_getSVGTextAndBg: function (t, e) {
								var i,
									n = [],
									r = [],
									o = t;
								this._setSVGBg(r);
								for (var s = 0, a = this._textLines.length; s < a; s++)
									(i = this._getLineLeftOffset(s)),
										(this.textBackgroundColor || this.styleHas('textBackgroundColor', s)) && this._setSVGTextLineBg(r, s, e + i, o),
										this._setSVGTextLineText(n, s, e + i, o),
										(o += this.getHeightOfLine(s));
								return { textSpans: n, textBgRects: r };
							},
							_createTextCharSpan: function (i, r, o, s) {
								var a = i !== i.trim() || i.match(e),
									c = this.getSvgSpanStyles(r, a),
									h = c ? 'style="' + c + '"' : '',
									l = r.deltaY,
									u = '',
									f = n.Object.NUM_FRACTION_DIGITS;
								return l && (u = ' dy="' + t(l, f) + '" '), ['<tspan x="', t(o, f), '" y="', t(s, f), '" ', u, h, '>', n.util.string.escapeXml(i), '</tspan>'].join('');
							},
							_setSVGTextLineText: function (t, e, i, r) {
								var o,
									s,
									a,
									c,
									h,
									l = this.getHeightOfLine(e),
									u = -1 !== this.textAlign.indexOf('justify'),
									f = '',
									d = 0,
									p = this._textLines[e];
								r += (l * (1 - this._fontSizeFraction)) / this.lineHeight;
								for (var g = 0, v = p.length - 1; g <= v; g++)
									(h = g === v || this.charSpacing),
										(f += p[g]),
										(a = this.__charBounds[e][g]),
										0 === d ? ((i += a.kernedWidth - a.width), (d += a.width)) : (d += a.kernedWidth),
										u && !h && this._reSpaceAndTab.test(p[g]) && (h = !0),
										h || ((o = o || this.getCompleteStyleDeclaration(e, g)), (s = this.getCompleteStyleDeclaration(e, g + 1)), (h = n.util.hasStyleChanged(o, s, !0))),
										h && ((c = this._getStyleDeclaration(e, g) || {}), t.push(this._createTextCharSpan(f, c, i, r)), (f = ''), (o = s), (i += d), (d = 0));
							},
							_pushTextBgRect: function (e, i, r, o, s, a) {
								var c = n.Object.NUM_FRACTION_DIGITS;
								e.push('\t\t<rect ', this._getFillAttributes(i), ' x="', t(r, c), '" y="', t(o, c), '" width="', t(s, c), '" height="', t(a, c), '"></rect>\n');
							},
							_setSVGTextLineBg: function (t, e, i, n) {
								for (
									var r,
										o,
										s = this._textLines[e],
										a = this.getHeightOfLine(e) / this.lineHeight,
										c = 0,
										h = 0,
										l = this.getValueOfPropertyAt(e, 0, 'textBackgroundColor'),
										u = 0,
										f = s.length;
									u < f;
									u++
								)
									(r = this.__charBounds[e][u]),
										(o = this.getValueOfPropertyAt(e, u, 'textBackgroundColor')),
										o !== l ? (l && this._pushTextBgRect(t, l, i + h, n, c, a), (h = r.left), (c = r.width), (l = o)) : (c += r.kernedWidth);
								o && this._pushTextBgRect(t, o, i + h, n, c, a);
							},
							_getFillAttributes: function (t) {
								var e = t && 'string' === typeof t ? new n.Color(t) : '';
								return e && e.getSource() && 1 !== e.getAlpha() ? 'opacity="' + e.getAlpha() + '" fill="' + e.setAlpha(1).toRgb() + '"' : 'fill="' + t + '"';
							},
							_getSVGLineTopOffset: function (t) {
								for (var e = 0, i = 0, n = 0; n < t; n++) e += this.getHeightOfLine(n);
								return (i = this.getHeightOfLine(n)), { lineTop: e, offset: ((this._fontSizeMult - this._fontSizeFraction) * i) / (this.lineHeight * this._fontSizeMult) };
							},
							getSvgStyles: function (t) {
								var e = n.Object.prototype.getSvgStyles.call(this, t);
								return e + ' white-space: pre;';
							}
						});
					})(),
					(function (t) {
						'use strict';
						var e = t.fabric || (t.fabric = {});
						(e.Textbox = e.util.createClass(e.IText, e.Observable, {
							type: 'textbox',
							minWidth: 20,
							dynamicMinWidth: 2,
							__cachedLines: null,
							lockScalingFlip: !0,
							noScaleCache: !1,
							_dimensionAffectingProps: e.Text.prototype._dimensionAffectingProps.concat('width'),
							_wordJoiners: /[ \t\r]/,
							splitByGrapheme: !1,
							initDimensions: function () {
								this.__skipDimension ||
									(this.isEditing && this.initDelayedCursor(),
									this.clearContextTop(),
									this._clearCache(),
									(this.dynamicMinWidth = 0),
									(this._styleMap = this._generateStyleMap(this._splitText())),
									this.dynamicMinWidth > this.width && this._set('width', this.dynamicMinWidth),
									-1 !== this.textAlign.indexOf('justify') && this.enlargeSpaces(),
									(this.height = this.calcTextHeight()),
									this.saveState({ propertySet: '_dimensionAffectingProps' }));
							},
							_generateStyleMap: function (t) {
								for (var e = 0, i = 0, n = 0, r = {}, o = 0; o < t.graphemeLines.length; o++)
									'\n' === t.graphemeText[n] && o > 0 ? ((i = 0), n++, e++) : !this.splitByGrapheme && this._reSpaceAndTab.test(t.graphemeText[n]) && o > 0 && (i++, n++),
										(r[o] = { line: e, offset: i }),
										(n += t.graphemeLines[o].length),
										(i += t.graphemeLines[o].length);
								return r;
							},
							styleHas: function (t, i) {
								if (this._styleMap && !this.isWrapping) {
									var n = this._styleMap[i];
									n && (i = n.line);
								}
								return e.Text.prototype.styleHas.call(this, t, i);
							},
							isEmptyStyles: function (t) {
								if (!this.styles) return !0;
								var e,
									i,
									n = 0,
									r = t + 1,
									o = !1,
									s = this._styleMap[t],
									a = this._styleMap[t + 1];
								for (var c in (s && ((t = s.line), (n = s.offset)),
								a && ((r = a.line), (o = r === t), (e = a.offset)),
								(i = 'undefined' === typeof t ? this.styles : { line: this.styles[t] }),
								i))
									for (var h in i[c]) if (h >= n && (!o || h < e)) for (var l in i[c][h]) return !1;
								return !0;
							},
							_getStyleDeclaration: function (t, e) {
								if (this._styleMap && !this.isWrapping) {
									var i = this._styleMap[t];
									if (!i) return null;
									(t = i.line), (e = i.offset + e);
								}
								return this.callSuper('_getStyleDeclaration', t, e);
							},
							_setStyleDeclaration: function (t, e, i) {
								var n = this._styleMap[t];
								(t = n.line), (e = n.offset + e), (this.styles[t][e] = i);
							},
							_deleteStyleDeclaration: function (t, e) {
								var i = this._styleMap[t];
								(t = i.line), (e = i.offset + e), delete this.styles[t][e];
							},
							_getLineStyle: function (t) {
								var e = this._styleMap[t];
								return !!this.styles[e.line];
							},
							_setLineStyle: function (t) {
								var e = this._styleMap[t];
								this.styles[e.line] = {};
							},
							_wrapText: function (t, e) {
								var i,
									n = [];
								for (this.isWrapping = !0, i = 0; i < t.length; i++) n = n.concat(this._wrapLine(t[i], i, e));
								return (this.isWrapping = !1), n;
							},
							_measureWord: function (t, e, i) {
								var n,
									r = 0,
									o = !0;
								i = i || 0;
								for (var s = 0, a = t.length; s < a; s++) {
									var c = this._getGraphemeBox(t[s], e, s + i, n, o);
									(r += c.kernedWidth), (n = t[s]);
								}
								return r;
							},
							_wrapLine: function (t, i, n, r) {
								var o = 0,
									s = this.splitByGrapheme,
									a = [],
									c = [],
									h = s ? e.util.string.graphemeSplit(t) : t.split(this._wordJoiners),
									l = '',
									u = 0,
									f = s ? '' : ' ',
									d = 0,
									p = 0,
									g = 0,
									v = !0,
									m = this._getWidthOfCharSpacing();
								r = r || 0;
								0 === h.length && h.push([]), (n -= r);
								for (var y = 0; y < h.length; y++)
									(l = s ? h[y] : e.util.string.graphemeSplit(h[y])),
										(d = this._measureWord(l, i, u)),
										(u += l.length),
										(o += p + d - m),
										o > n && !v ? (a.push(c), (c = []), (o = d), (v = !0)) : (o += m),
										v || s || c.push(f),
										(c = c.concat(l)),
										(p = s ? 0 : this._measureWord([f], i, u)),
										u++,
										(v = !1),
										d > g && (g = d);
								return y && a.push(c), g + r > this.dynamicMinWidth && (this.dynamicMinWidth = g - m + r), a;
							},
							isEndOfWrapping: function (t) {
								return !this._styleMap[t + 1] || this._styleMap[t + 1].line !== this._styleMap[t].line;
							},
							missingNewlineOffset: function (t) {
								return this.splitByGrapheme ? (this.isEndOfWrapping(t) ? 1 : 0) : 1;
							},
							_splitTextIntoLines: function (t) {
								for (var i = e.Text.prototype._splitTextIntoLines.call(this, t), n = this._wrapText(i.lines, this.width), r = new Array(n.length), o = 0; o < n.length; o++)
									r[o] = n[o].join('');
								return (i.lines = r), (i.graphemeLines = n), i;
							},
							getMinWidth: function () {
								return Math.max(this.minWidth, this.dynamicMinWidth);
							},
							_removeExtraneousStyles: function () {
								var t = {};
								for (var e in this._styleMap) this._textLines[e] && (t[this._styleMap[e].line] = 1);
								for (var e in this.styles) t[e] || delete this.styles[e];
							},
							toObject: function (t) {
								return this.callSuper('toObject', ['minWidth', 'splitByGrapheme'].concat(t));
							}
						})),
							(e.Textbox.fromObject = function (t, i) {
								return (t.styles = e.util.stylesFromArray(t.styles, t.text)), e.Object._fromObject('Textbox', t, i, 'text');
							});
					})(e),
					(function () {
						var t = n.controlsUtils,
							e = t.scaleSkewCursorStyleHandler,
							i = t.scaleCursorStyleHandler,
							r = t.scalingEqually,
							o = t.scalingYOrSkewingX,
							s = t.scalingXOrSkewingY,
							a = t.scaleOrSkewActionName,
							c = n.Object.prototype.controls;
						if (
							((c.ml = new n.Control({ x: -0.5, y: 0, cursorStyleHandler: e, actionHandler: s, getActionName: a })),
							(c.mr = new n.Control({ x: 0.5, y: 0, cursorStyleHandler: e, actionHandler: s, getActionName: a })),
							(c.mb = new n.Control({ x: 0, y: 0.5, cursorStyleHandler: e, actionHandler: o, getActionName: a })),
							(c.mt = new n.Control({ x: 0, y: -0.5, cursorStyleHandler: e, actionHandler: o, getActionName: a })),
							(c.tl = new n.Control({ x: -0.5, y: -0.5, cursorStyleHandler: i, actionHandler: r })),
							(c.tr = new n.Control({ x: 0.5, y: -0.5, cursorStyleHandler: i, actionHandler: r })),
							(c.bl = new n.Control({ x: -0.5, y: 0.5, cursorStyleHandler: i, actionHandler: r })),
							(c.br = new n.Control({ x: 0.5, y: 0.5, cursorStyleHandler: i, actionHandler: r })),
							(c.mtr = new n.Control({
								x: 0,
								y: -0.5,
								actionHandler: t.rotationWithSnapping,
								cursorStyleHandler: t.rotationStyleHandler,
								offsetY: -40,
								withConnection: !0,
								actionName: 'rotate'
							})),
							n.Textbox)
						) {
							var h = (n.Textbox.prototype.controls = {});
							(h.mtr = c.mtr),
								(h.tr = c.tr),
								(h.br = c.br),
								(h.tl = c.tl),
								(h.bl = c.bl),
								(h.mt = c.mt),
								(h.mb = c.mb),
								(h.mr = new n.Control({ x: 0.5, y: 0, actionHandler: t.changeWidth, cursorStyleHandler: e, actionName: 'resizing' })),
								(h.ml = new n.Control({ x: -0.5, y: 0, actionHandler: t.changeWidth, cursorStyleHandler: e, actionName: 'resizing' }));
						}
					})();
			},
			3755: function (t) {
				var e = '0.7.28',
					i = '',
					n = '?',
					r = 'function',
					o = 'undefined',
					s = 'object',
					a = 'string',
					c = 'major',
					h = 'model',
					l = 'name',
					u = 'type',
					f = 'vendor',
					d = 'version',
					p = 'architecture',
					g = 'console',
					v = 'mobile',
					m = 'tablet',
					y = 'smarttv',
					b = 'wearable',
					x = 'embedded',
					_ = 255,
					w = 'Amazon',
					C = 'Apple',
					S = 'ASUS',
					T = 'BlackBerry',
					O = 'Browser',
					k = 'Chrome',
					P = 'Edge',
					E = 'Firefox',
					M = 'Google',
					j = 'Huawei',
					D = 'LG',
					A = 'Microsoft',
					F = 'Motorola',
					L = 'Opera',
					I = 'Samsung',
					R = 'Sony',
					B = 'Xiaomi',
					z = 'Zebra',
					X = function (t, e) {
						var i = {};
						for (var n in t) e[n] && e[n].length % 2 === 0 ? (i[n] = e[n].concat(t[n])) : (i[n] = t[n]);
						return i;
					},
					W = function (t) {
						var e = {};
						for (var i in t) e[t[i].toUpperCase()] = t[i];
						return e;
					},
					Y = function (t, e) {
						return typeof t === a && -1 !== H(e).indexOf(H(t));
					},
					H = function (t) {
						return t.toLowerCase();
					},
					G = function (t) {
						return typeof t === a ? t.replace(/[^\d\.]/g, i).split('.')[0] : void 0;
					},
					U = function (t, e) {
						if (typeof t === a) return (t = t.replace(/^\s+|\s+$/g, i)), typeof e === o ? t : t.substring(0, _);
					},
					N = function (t, e) {
						var i,
							n,
							o,
							a,
							c,
							h,
							l = 0;
						while (l < e.length && !c) {
							var u = e[l],
								f = e[l + 1];
							i = n = 0;
							while (i < u.length && !c)
								if (((c = u[i++].exec(t)), c))
									for (o = 0; o < f.length; o++)
										(h = c[++n]),
											(a = f[o]),
											typeof a === s && a.length > 0
												? 2 == a.length
													? typeof a[1] == r
														? (this[a[0]] = a[1].call(this, h))
														: (this[a[0]] = a[1])
													: 3 == a.length
													? typeof a[1] !== r || (a[1].exec && a[1].test)
														? (this[a[0]] = h ? h.replace(a[1], a[2]) : void 0)
														: (this[a[0]] = h ? a[1].call(this, h, a[2]) : void 0)
													: 4 == a.length && (this[a[0]] = h ? a[3].call(this, h.replace(a[1], a[2])) : void 0)
												: (this[a] = h || void 0);
							l += 2;
						}
					},
					V = function (t, e) {
						for (var i in e)
							if (typeof e[i] === s && e[i].length > 0) {
								for (var r = 0; r < e[i].length; r++) if (Y(e[i][r], t)) return i === n ? void 0 : i;
							} else if (Y(e[i], t)) return i === n ? void 0 : i;
						return t;
					},
					q = { '1.0': '/8', 1.2: '/1', 1.3: '/3', '2.0': '/412', '2.0.2': '/416', '2.0.3': '/417', '2.0.4': '/419', '?': '/' },
					K = {
						ME: '4.90',
						'NT 3.11': 'NT3.51',
						'NT 4.0': 'NT4.0',
						2e3: 'NT 5.0',
						XP: ['NT 5.1', 'NT 5.2'],
						Vista: 'NT 6.0',
						7: 'NT 6.1',
						8: 'NT 6.2',
						8.1: 'NT 6.3',
						10: ['NT 6.4', 'NT 10.0'],
						RT: 'ARM'
					},
					Z = {
						browser: [
							[/\b(?:crmo|crios)\/([\w\.]+)/i],
							[d, [l, 'Chrome']],
							[/edg(?:e|ios|a)?\/([\w\.]+)/i],
							[d, [l, 'Edge']],
							[/(opera mini)\/([-\w\.]+)/i, /(opera [mobiletab]{3,6})\b.+version\/([-\w\.]+)/i, /(opera)(?:.+version\/|[\/ ]+)([\w\.]+)/i],
							[l, d],
							[/opios[\/ ]+([\w\.]+)/i],
							[d, [l, L + ' Mini']],
							[/\bopr\/([\w\.]+)/i],
							[d, [l, L]],
							[
								/(kindle)\/([\w\.]+)/i,
								/(lunascape|maxthon|netfront|jasmine|blazer)[\/ ]?([\w\.]*)/i,
								/(avant |iemobile|slim)(?:browser)?[\/ ]?([\w\.]*)/i,
								/(ba?idubrowser)[\/ ]?([\w\.]+)/i,
								/(?:ms|\()(ie) ([\w\.]+)/i,
								/(flock|rockmelt|midori|epiphany|silk|skyfire|ovibrowser|bolt|iron|vivaldi|iridium|phantomjs|bowser|quark|qupzilla|falkon|rekonq|puffin|brave|whale|qqbrowserlite|qq)\/([-\w\.]+)/i,
								/(weibo)__([\d\.]+)/i
							],
							[l, d],
							[/(?:\buc? ?browser|(?:juc.+)ucweb)[\/ ]?([\w\.]+)/i],
							[d, [l, 'UC' + O]],
							[/\bqbcore\/([\w\.]+)/i],
							[d, [l, 'WeChat(Win) Desktop']],
							[/micromessenger\/([\w\.]+)/i],
							[d, [l, 'WeChat']],
							[/konqueror\/([\w\.]+)/i],
							[d, [l, 'Konqueror']],
							[/trident.+rv[: ]([\w\.]{1,9})\b.+like gecko/i],
							[d, [l, 'IE']],
							[/yabrowser\/([\w\.]+)/i],
							[d, [l, 'Yandex']],
							[/(avast|avg)\/([\w\.]+)/i],
							[[l, /(.+)/, '$1 Secure ' + O], d],
							[/\bfocus\/([\w\.]+)/i],
							[d, [l, E + ' Focus']],
							[/\bopt\/([\w\.]+)/i],
							[d, [l, L + ' Touch']],
							[/coc_coc\w+\/([\w\.]+)/i],
							[d, [l, 'Coc Coc']],
							[/dolfin\/([\w\.]+)/i],
							[d, [l, 'Dolphin']],
							[/coast\/([\w\.]+)/i],
							[d, [l, L + ' Coast']],
							[/miuibrowser\/([\w\.]+)/i],
							[d, [l, 'MIUI ' + O]],
							[/fxios\/([-\w\.]+)/i],
							[d, [l, E]],
							[/\bqihu|(qi?ho?o?|360)browser/i],
							[[l, '360 ' + O]],
							[/(oculus|samsung|sailfish)browser\/([\w\.]+)/i],
							[[l, /(.+)/, '$1 ' + O], d],
							[/(comodo_dragon)\/([\w\.]+)/i],
							[[l, /_/g, ' '], d],
							[/(electron)\/([\w\.]+) safari/i, /(tesla)(?: qtcarbrowser|\/(20\d\d\.[-\w\.]+))/i, /m?(qqbrowser|baiduboxapp|2345Explorer)[\/ ]?([\w\.]+)/i],
							[l, d],
							[/(metasr)[\/ ]?([\w\.]+)/i, /(lbbrowser)/i],
							[l],
							[/((?:fban\/fbios|fb_iab\/fb4a)(?!.+fbav)|;fbav\/([\w\.]+);)/i],
							[[l, 'Facebook'], d],
							[/safari (line)\/([\w\.]+)/i, /\b(line)\/([\w\.]+)\/iab/i, /(chromium|instagram)[\/ ]([-\w\.]+)/i],
							[l, d],
							[/\bgsa\/([\w\.]+) .*safari\//i],
							[d, [l, 'GSA']],
							[/headlesschrome(?:\/([\w\.]+)| )/i],
							[d, [l, k + ' Headless']],
							[/ wv\).+(chrome)\/([\w\.]+)/i],
							[[l, k + ' WebView'], d],
							[/droid.+ version\/([\w\.]+)\b.+(?:mobile safari|safari)/i],
							[d, [l, 'Android ' + O]],
							[/(chrome|omniweb|arora|[tizenoka]{5} ?browser)\/v?([\w\.]+)/i],
							[l, d],
							[/version\/([\w\.]+) .*mobile\/\w+ (safari)/i],
							[d, [l, 'Mobile Safari']],
							[/version\/([\w\.]+) .*(mobile ?safari|safari)/i],
							[d, l],
							[/webkit.+?(mobile ?safari|safari)(\/[\w\.]+)/i],
							[l, [d, V, q]],
							[/(webkit|khtml)\/([\w\.]+)/i],
							[l, d],
							[/(navigator|netscape\d?)\/([-\w\.]+)/i],
							[[l, 'Netscape'], d],
							[/mobile vr; rv:([\w\.]+)\).+firefox/i],
							[d, [l, E + ' Reality']],
							[
								/ekiohf.+(flow)\/([\w\.]+)/i,
								/(swiftfox)/i,
								/(icedragon|iceweasel|camino|chimera|fennec|maemo browser|minimo|conkeror|klar)[\/ ]?([\w\.\+]+)/i,
								/(seamonkey|k-meleon|icecat|iceape|firebird|phoenix|palemoon|basilisk|waterfox)\/([-\w\.]+)$/i,
								/(firefox)\/([\w\.]+)/i,
								/(mozilla)\/([\w\.]+) .+rv\:.+gecko\/\d+/i,
								/(polaris|lynx|dillo|icab|doris|amaya|w3m|netsurf|sleipnir|obigo|mosaic|(?:go|ice|up)[\. ]?browser)[-\/ ]?v?([\w\.]+)/i,
								/(links) \(([\w\.]+)/i
							],
							[l, d]
						],
						cpu: [
							[/(?:(amd|x(?:(?:86|64)[-_])?|wow|win)64)[;\)]/i],
							[[p, 'amd64']],
							[/(ia32(?=;))/i],
							[[p, H]],
							[/((?:i[346]|x)86)[;\)]/i],
							[[p, 'ia32']],
							[/\b(aarch64|arm(v?8e?l?|_?64))\b/i],
							[[p, 'arm64']],
							[/\b(arm(?:v[67])?ht?n?[fl]p?)\b/i],
							[[p, 'armhf']],
							[/windows (ce|mobile); ppc;/i],
							[[p, 'arm']],
							[/((?:ppc|powerpc)(?:64)?)(?: mac|;|\))/i],
							[[p, /ower/, i, H]],
							[/(sun4\w)[;\)]/i],
							[[p, 'sparc']],
							[/((?:avr32|ia64(?=;))|68k(?=\))|\barm(?=v(?:[1-7]|[5-7]1)l?|;|eabi)|(?=atmel )avr|(?:irix|mips|sparc)(?:64)?\b|pa-risc)/i],
							[[p, H]]
						],
						device: [
							[/\b(sch-i[89]0\d|shw-m380s|sm-[pt]\w{2,4}|gt-[pn]\d{2,4}|sgh-t8[56]9|nexus 10)/i],
							[h, [f, I], [u, m]],
							[/\b((?:s[cgp]h|gt|sm)-\w+|galaxy nexus)/i, /samsung[- ]([-\w]+)/i, /sec-(sgh\w+)/i],
							[h, [f, I], [u, v]],
							[/\((ip(?:hone|od)[\w ]*);/i],
							[h, [f, C], [u, v]],
							[/\((ipad);[-\w\),; ]+apple/i, /applecoremedia\/[\w\.]+ \((ipad)/i, /\b(ipad)\d\d?,\d\d?[;\]].+ios/i],
							[h, [f, C], [u, m]],
							[/\b((?:ag[rs][23]?|bah2?|sht?|btv)-a?[lw]\d{2})\b(?!.+d\/s)/i],
							[h, [f, j], [u, m]],
							[/(?:huawei|honor)([-\w ]+)[;\)]/i, /\b(nexus 6p|\w{2,4}-[atu]?[ln][01259x][012359][an]?)\b(?!.+d\/s)/i],
							[h, [f, j], [u, v]],
							[
								/\b(poco[\w ]+)(?: bui|\))/i,
								/\b; (\w+) build\/hm\1/i,
								/\b(hm[-_ ]?note?[_ ]?(?:\d\w)?) bui/i,
								/\b(redmi[\-_ ]?(?:note|k)?[\w_ ]+)(?: bui|\))/i,
								/\b(mi[-_ ]?(?:a\d|one|one[_ ]plus|note lte|max)?[_ ]?(?:\d?\w?)[_ ]?(?:plus|se|lite)?)(?: bui|\))/i
							],
							[
								[h, /_/g, ' '],
								[f, B],
								[u, v]
							],
							[/\b(mi[-_ ]?(?:pad)(?:[\w_ ]+))(?: bui|\))/i],
							[
								[h, /_/g, ' '],
								[f, B],
								[u, m]
							],
							[/; (\w+) bui.+ oppo/i, /\b(cph[12]\d{3}|p(?:af|c[al]|d\w|e[ar])[mt]\d0|x9007)\b/i],
							[h, [f, 'OPPO'], [u, v]],
							[/vivo (\w+)(?: bui|\))/i, /\b(v[12]\d{3}\w?[at])(?: bui|;)/i],
							[h, [f, 'Vivo'], [u, v]],
							[/\b(rmx[12]\d{3})(?: bui|;|\))/i],
							[h, [f, 'Realme'], [u, v]],
							[/\b(milestone|droid(?:[2-4x]| (?:bionic|x2|pro|razr))?:?( 4g)?)\b[\w ]+build\//i, /\bmot(?:orola)?[- ](\w*)/i, /((?:moto[\w\(\) ]+|xt\d{3,4}|nexus 6)(?= bui|\)))/i],
							[h, [f, F], [u, v]],
							[/\b(mz60\d|xoom[2 ]{0,2}) build\//i],
							[h, [f, F], [u, m]],
							[/((?=lg)?[vl]k\-?\d{3}) bui| 3\.[-\w; ]{10}lg?-([06cv9]{3,4})/i],
							[h, [f, D], [u, m]],
							[/(lm(?:-?f100[nv]?|-[\w\.]+)(?= bui|\))|nexus [45])/i, /\blg[-e;\/ ]+((?!browser|netcast|android tv)\w+)/i, /\blg-?([\d\w]+) bui/i],
							[h, [f, D], [u, v]],
							[/(ideatab[-\w ]+)/i, /lenovo ?(s[56]000[-\w]+|tab(?:[\w ]+)|yt[-\d\w]{6}|tb[-\d\w]{6})/i],
							[h, [f, 'Lenovo'], [u, m]],
							[/(?:maemo|nokia).*(n900|lumia \d+)/i, /nokia[-_ ]?([-\w\.]*)/i],
							[
								[h, /_/g, ' '],
								[f, 'Nokia'],
								[u, v]
							],
							[/(pixel c)\b/i],
							[h, [f, M], [u, m]],
							[/droid.+; (pixel[\daxl ]{0,6})(?: bui|\))/i],
							[h, [f, M], [u, v]],
							[/droid.+ ([c-g]\d{4}|so[-l]\w+|xq-a\w[4-7][12])(?= bui|\).+chrome\/(?![1-6]{0,1}\d\.))/i],
							[h, [f, R], [u, v]],
							[/sony tablet [ps]/i, /\b(?:sony)?sgp\w+(?: bui|\))/i],
							[
								[h, 'Xperia Tablet'],
								[f, R],
								[u, m]
							],
							[/ (kb2005|in20[12]5|be20[12][59])\b/i, /(?:one)?(?:plus)? (a\d0\d\d)(?: b|\))/i],
							[h, [f, 'OnePlus'], [u, v]],
							[/(alexa)webm/i, /(kf[a-z]{2}wi)( bui|\))/i, /(kf[a-z]+)( bui|\)).+silk\//i],
							[h, [f, w], [u, m]],
							[/((?:sd|kf)[0349hijorstuw]+)( bui|\)).+silk\//i],
							[
								[h, /(.+)/g, 'Fire Phone $1'],
								[f, w],
								[u, v]
							],
							[/(playbook);[-\w\),; ]+(rim)/i],
							[h, f, [u, m]],
							[/\b((?:bb[a-f]|st[hv])100-\d)/i, /\(bb10; (\w+)/i],
							[h, [f, T], [u, v]],
							[/(?:\b|asus_)(transfo[prime ]{4,10} \w+|eeepc|slider \w+|nexus 7|padfone|p00[cj])/i],
							[h, [f, S], [u, m]],
							[/ (z[bes]6[027][012][km][ls]|zenfone \d\w?)\b/i],
							[h, [f, S], [u, v]],
							[/(nexus 9)/i],
							[h, [f, 'HTC'], [u, m]],
							[/(htc)[-;_ ]{1,2}([\w ]+(?=\)| bui)|\w+)/i, /(zte)[- ]([\w ]+?)(?: bui|\/|\))/i, /(alcatel|geeksphone|nexian|panasonic|sony)[-_ ]?([-\w]*)/i],
							[f, [h, /_/g, ' '], [u, v]],
							[/droid.+; ([ab][1-7]-?[0178a]\d\d?)/i],
							[h, [f, 'Acer'], [u, m]],
							[/droid.+; (m[1-5] note) bui/i, /\bmz-([-\w]{2,})/i],
							[h, [f, 'Meizu'], [u, v]],
							[/\b(sh-?[altvz]?\d\d[a-ekm]?)/i],
							[h, [f, 'Sharp'], [u, v]],
							[
								/(blackberry|benq|palm(?=\-)|sonyericsson|acer|asus|dell|meizu|motorola|polytron)[-_ ]?([-\w]*)/i,
								/(hp) ([\w ]+\w)/i,
								/(asus)-?(\w+)/i,
								/(microsoft); (lumia[\w ]+)/i,
								/(lenovo)[-_ ]?([-\w]+)/i,
								/(jolla)/i,
								/(oppo) ?([\w ]+) bui/i
							],
							[f, h, [u, v]],
							[
								/(archos) (gamepad2?)/i,
								/(hp).+(touchpad(?!.+tablet)|tablet)/i,
								/(kindle)\/([\w\.]+)/i,
								/(nook)[\w ]+build\/(\w+)/i,
								/(dell) (strea[kpr\d ]*[\dko])/i,
								/(le[- ]+pan)[- ]+(\w{1,9}) bui/i,
								/(trinity)[- ]*(t\d{3}) bui/i,
								/(gigaset)[- ]+(q\w{1,9}) bui/i,
								/(vodafone) ([\w ]+)(?:\)| bui)/i
							],
							[f, h, [u, m]],
							[/(surface duo)/i],
							[h, [f, A], [u, m]],
							[/droid [\d\.]+; (fp\du?)(?: b|\))/i],
							[h, [f, 'Fairphone'], [u, v]],
							[/(u304aa)/i],
							[h, [f, 'AT&T'], [u, v]],
							[/\bsie-(\w*)/i],
							[h, [f, 'Siemens'], [u, v]],
							[/\b(rct\w+) b/i],
							[h, [f, 'RCA'], [u, m]],
							[/\b(venue[\d ]{2,7}) b/i],
							[h, [f, 'Dell'], [u, m]],
							[/\b(q(?:mv|ta)\w+) b/i],
							[h, [f, 'Verizon'], [u, m]],
							[/\b(?:barnes[& ]+noble |bn[rt])([\w\+ ]*) b/i],
							[h, [f, 'Barnes & Noble'], [u, m]],
							[/\b(tm\d{3}\w+) b/i],
							[h, [f, 'NuVision'], [u, m]],
							[/\b(k88) b/i],
							[h, [f, 'ZTE'], [u, m]],
							[/\b(nx\d{3}j) b/i],
							[h, [f, 'ZTE'], [u, v]],
							[/\b(gen\d{3}) b.+49h/i],
							[h, [f, 'Swiss'], [u, v]],
							[/\b(zur\d{3}) b/i],
							[h, [f, 'Swiss'], [u, m]],
							[/\b((zeki)?tb.*\b) b/i],
							[h, [f, 'Zeki'], [u, m]],
							[/\b([yr]\d{2}) b/i, /\b(dragon[- ]+touch |dt)(\w{5}) b/i],
							[[f, 'Dragon Touch'], h, [u, m]],
							[/\b(ns-?\w{0,9}) b/i],
							[h, [f, 'Insignia'], [u, m]],
							[/\b((nxa|next)-?\w{0,9}) b/i],
							[h, [f, 'NextBook'], [u, m]],
							[/\b(xtreme\_)?(v(1[045]|2[015]|[3469]0|7[05])) b/i],
							[[f, 'Voice'], h, [u, v]],
							[/\b(lvtel\-)?(v1[12]) b/i],
							[[f, 'LvTel'], h, [u, v]],
							[/\b(ph-1) /i],
							[h, [f, 'Essential'], [u, v]],
							[/\b(v(100md|700na|7011|917g).*\b) b/i],
							[h, [f, 'Envizen'], [u, m]],
							[/\b(trio[-\w\. ]+) b/i],
							[h, [f, 'MachSpeed'], [u, m]],
							[/\btu_(1491) b/i],
							[h, [f, 'Rotor'], [u, m]],
							[/(shield[\w ]+) b/i],
							[h, [f, 'Nvidia'], [u, m]],
							[/(sprint) (\w+)/i],
							[f, h, [u, v]],
							[/(kin\.[onetw]{3})/i],
							[
								[h, /\./g, ' '],
								[f, A],
								[u, v]
							],
							[/droid.+; (cc6666?|et5[16]|mc[239][23]x?|vc8[03]x?)\)/i],
							[h, [f, z], [u, m]],
							[/droid.+; (ec30|ps20|tc[2-8]\d[kx])\)/i],
							[h, [f, z], [u, v]],
							[/(ouya)/i, /(nintendo) ([wids3utch]+)/i],
							[f, h, [u, g]],
							[/droid.+; (shield) bui/i],
							[h, [f, 'Nvidia'], [u, g]],
							[/(playstation [345portablevi]+)/i],
							[h, [f, R], [u, g]],
							[/\b(xbox(?: one)?(?!; xbox))[\); ]/i],
							[h, [f, A], [u, g]],
							[/smart-tv.+(samsung)/i],
							[f, [u, y]],
							[/hbbtv.+maple;(\d+)/i],
							[
								[h, /^/, 'SmartTV'],
								[f, I],
								[u, y]
							],
							[/(nux; netcast.+smarttv|lg (netcast\.tv-201\d|android tv))/i],
							[
								[f, D],
								[u, y]
							],
							[/(apple) ?tv/i],
							[f, [h, C + ' TV'], [u, y]],
							[/crkey/i],
							[
								[h, k + 'cast'],
								[f, M],
								[u, y]
							],
							[/droid.+aft(\w)( bui|\))/i],
							[h, [f, w], [u, y]],
							[/\(dtv[\);].+(aquos)/i],
							[h, [f, 'Sharp'], [u, y]],
							[/\b(roku)[\dx]*[\)\/]((?:dvp-)?[\d\.]*)/i, /hbbtv\/\d+\.\d+\.\d+ +\([\w ]*; *(\w[^;]*);([^;]*)/i],
							[
								[f, U],
								[h, U],
								[u, y]
							],
							[/\b(android tv|smart[- ]?tv|opera tv|tv; rv:)\b/i],
							[[u, y]],
							[/((pebble))app/i],
							[f, h, [u, b]],
							[/droid.+; (glass) \d/i],
							[h, [f, M], [u, b]],
							[/droid.+; (wt63?0{2,3})\)/i],
							[h, [f, z], [u, b]],
							[/(tesla)(?: qtcarbrowser|\/[-\w\.]+)/i],
							[f, [u, x]],
							[/droid .+?; ([^;]+?)(?: bui|\) applew).+? mobile safari/i],
							[h, [u, v]],
							[/droid .+?; ([^;]+?)(?: bui|\) applew).+?(?! mobile) safari/i],
							[h, [u, m]],
							[/\b((tablet|tab)[;\/]|focus\/\d(?!.+mobile))/i],
							[[u, m]],
							[/(phone|mobile(?:[;\/]| safari)|pda(?=.+windows ce))/i],
							[[u, v]],
							[/(android[-\w\. ]{0,9});.+buil/i],
							[h, [f, 'Generic']]
						],
						engine: [
							[/windows.+ edge\/([\w\.]+)/i],
							[d, [l, P + 'HTML']],
							[/webkit\/537\.36.+chrome\/(?!27)([\w\.]+)/i],
							[d, [l, 'Blink']],
							[
								/(presto)\/([\w\.]+)/i,
								/(webkit|trident|netfront|netsurf|amaya|lynx|w3m|goanna)\/([\w\.]+)/i,
								/ekioh(flow)\/([\w\.]+)/i,
								/(khtml|tasman|links)[\/ ]\(?([\w\.]+)/i,
								/(icab)[\/ ]([23]\.[\d\.]+)/i
							],
							[l, d],
							[/rv\:([\w\.]{1,9})\b.+(gecko)/i],
							[d, l]
						],
						os: [
							[/microsoft (windows) (vista|xp)/i],
							[l, d],
							[/(windows) nt 6\.2; (arm)/i, /(windows (?:phone(?: os)?|mobile))[\/ ]?([\d\.\w ]*)/i, /(windows)[\/ ]?([ntce\d\. ]+\w)(?!.+xbox)/i],
							[l, [d, V, K]],
							[/(win(?=3|9|n)|win 9x )([nt\d\.]+)/i],
							[
								[l, 'Windows'],
								[d, V, K]
							],
							[/ip[honead]{2,4}\b(?:.*os ([\w]+) like mac|; opera)/i, /cfnetwork\/.+darwin/i],
							[
								[d, /_/g, '.'],
								[l, 'iOS']
							],
							[/(mac os x) ?([\w\. ]*)/i, /(macintosh|mac_powerpc\b)(?!.+haiku)/i],
							[
								[l, 'Mac OS'],
								[d, /_/g, '.']
							],
							[/droid ([\w\.]+)\b.+(android[- ]x86)/i],
							[d, l],
							[/(android|webos|qnx|bada|rim tablet os|maemo|meego|sailfish)[-\/ ]?([\w\.]*)/i, /(blackberry)\w*\/([\w\.]*)/i, /(tizen|kaios)[\/ ]([\w\.]+)/i, /\((series40);/i],
							[l, d],
							[/\(bb(10);/i],
							[d, [l, T]],
							[/(?:symbian ?os|symbos|s60(?=;)|series60)[-\/ ]?([\w\.]*)/i],
							[d, [l, 'Symbian']],
							[/mozilla\/[\d\.]+ \((?:mobile|tablet|tv|mobile; [\w ]+); rv:.+ gecko\/([\w\.]+)/i],
							[d, [l, E + ' OS']],
							[/web0s;.+rt(tv)/i, /\b(?:hp)?wos(?:browser)?\/([\w\.]+)/i],
							[d, [l, 'webOS']],
							[/crkey\/([\d\.]+)/i],
							[d, [l, k + 'cast']],
							[/(cros) [\w]+ ([\w\.]+\w)/i],
							[[l, 'Chromium OS'], d],
							[
								/(nintendo|playstation) ([wids345portablevuch]+)/i,
								/(xbox); +xbox ([^\);]+)/i,
								/\b(joli|palm)\b ?(?:os)?\/?([\w\.]*)/i,
								/(mint)[\/\(\) ]?(\w*)/i,
								/(mageia|vectorlinux)[; ]/i,
								/([kxln]?ubuntu|debian|suse|opensuse|gentoo|arch(?= linux)|slackware|fedora|mandriva|centos|pclinuxos|red ?hat|zenwalk|linpus|raspbian|plan 9|minix|risc os|contiki|deepin|manjaro|elementary os|sabayon|linspire)(?: gnu\/linux)?(?: enterprise)?(?:[- ]linux)?(?:-gnu)?[-\/ ]?(?!chrom|package)([-\w\.]*)/i,
								/(hurd|linux) ?([\w\.]*)/i,
								/(gnu) ?([\w\.]*)/i,
								/\b([-frentopcghs]{0,5}bsd|dragonfly)[\/ ]?(?!amd|[ix346]{1,2}86)([\w\.]*)/i,
								/(haiku) (\w+)/i
							],
							[l, d],
							[/(sunos) ?([\w\.\d]*)/i],
							[[l, 'Solaris'], d],
							[/((?:open)?solaris)[-\/ ]?([\w\.]*)/i, /(aix) ((\d)(?=\.|\)| )[\w\.])*/i, /\b(beos|os\/2|amigaos|morphos|openvms|fuchsia|hp-ux)/i, /(unix) ?([\w\.]*)/i],
							[l, d]
						]
					},
					J = function (t, e) {
						if ((typeof t === s && ((e = t), (t = void 0)), !(this instanceof J))) return new J(t, e).getResult();
						var n = t || (typeof window !== o && window.navigator && window.navigator.userAgent ? window.navigator.userAgent : i),
							r = e ? X(Z, e) : Z;
						return (
							(this.getBrowser = function () {
								var t = {};
								return (t[l] = void 0), (t[d] = void 0), N.call(t, n, r.browser), (t.major = G(t.version)), t;
							}),
							(this.getCPU = function () {
								var t = {};
								return (t[p] = void 0), N.call(t, n, r.cpu), t;
							}),
							(this.getDevice = function () {
								var t = {};
								return (t[f] = void 0), (t[h] = void 0), (t[u] = void 0), N.call(t, n, r.device), t;
							}),
							(this.getEngine = function () {
								var t = {};
								return (t[l] = void 0), (t[d] = void 0), N.call(t, n, r.engine), t;
							}),
							(this.getOS = function () {
								var t = {};
								return (t[l] = void 0), (t[d] = void 0), N.call(t, n, r.os), t;
							}),
							(this.getResult = function () {
								return { ua: this.getUA(), browser: this.getBrowser(), engine: this.getEngine(), os: this.getOS(), device: this.getDevice(), cpu: this.getCPU() };
							}),
							(this.getUA = function () {
								return n;
							}),
							(this.setUA = function (t) {
								return (n = typeof t === a && t.length > _ ? U(t, _) : t), this;
							}),
							this.setUA(n),
							this
						);
					};
				(J.VERSION = e), (J.BROWSER = W([l, d, c])), (J.CPU = W([p])), (J.DEVICE = W([h, f, u, g, v, y, m, b, x])), (J.ENGINE = J.OS = W([l, d])), (t.exports = { UAParser: J });
			},
			3028: function (t, e, i) {
				'use strict';
				var n = i(144),
					r = function () {
						var t = this,
							e = t._self._c;
						return e('div', { attrs: { id: 'app' } }, [
							e(
								'div',
								{ staticClass: 'white-board-wrapper', attrs: { id: 'zco-white-board-wrapper' } },
								[t.isMobile ? e('ToolbarMobile', { attrs: { offsetTop: t.offsetTop } }) : e('ToolBar'), e('WhiteBoard', { attrs: { offsetTop: t.offsetTop } })],
								1
							)
						]);
					},
					o = [],
					s = function () {
						var t = this,
							e = t._self._c;
						return e(
							'div',
							{ staticClass: 'toolbar-container' },
							[
								e('ul', { staticClass: 'tools', attrs: { id: 'toolsul' } }, [
									e(
										'li',
										{ class: 'selector' === t.drawType ? 'active' : '', attrs: { id: 'pointer-select', 'data-type': 'pointer' }, on: { click: e => t.select('selector', e) } },
										[e('i', { staticClass: 'icon-tools icon-pointer-black', attrs: { 'data-default': 'icon-tools icon-pointer-black' } })]
									),
									e('li', { attrs: { id: 'color-select', 'data-type': 'color' }, on: { click: t.changeColor } }, [
										e('i', {
											staticClass: 'icon-tools icon-color-black',
											style: { backgroundColor: t.color, border: '#FFFFFF' === t.color ? '1px solid #999999' : '' },
											attrs: { 'data-default': 'icon-tools icon-color-black' }
										})
									]),
									e('li', { class: 'pen' === t.drawType ? 'active' : '', attrs: { id: 'toolsPencil', 'data-type': 'pen' }, on: { click: e => t.select('pen', e) } }, [
										e('i', { staticClass: 'icon-tools icon-pen-black', attrs: { 'data-default': 'icon-tools icon-pen-black' } })
									]),
									e('li', { class: t.isLineType() ? 'active' : '', attrs: { 'data-type': 'lines' }, on: { click: t.lines } }, [
										e('i', { staticClass: 'icon-tools icon-lines-black', attrs: { id: 'lines', 'data-default': 'icon-tools icon-lines-black' } })
									]),
									e('li', { class: t.isShapeType() ? 'active' : '', attrs: { 'data-type': 'shape' }, on: { click: t.shapes } }, [
										e('i', { staticClass: 'icon-tools icon-shape-black', attrs: { id: 'shape', 'data-default': 'icon-tools icon-shape-black' } })
									]),
									e('li', { class: 'text' !== t.drawType || t.isTextCreate ? '' : 'active', attrs: { 'data-type': 'text' }, on: { click: e => t.select('text', e) } }, [
										e('i', { staticClass: 'icon-tools icon-text-black', attrs: { 'data-default': 'icon-tools icon-text-black' } })
									]),
									e('li', { class: 'remove' === t.drawType ? 'active' : '', attrs: { 'data-type': 'remove' }, on: { click: e => t.select('remove', e) } }, [
										e('i', { staticClass: 'icon-tools icon-remove-black', attrs: { 'data-default': 'icon-tools icon-remove-black' } })
									])
								]),
								t.isShowColor
									? e('ColorPad', {
											attrs: { isMobile: !1 },
											on: {
												hide: function (e) {
													t.isShowColor = !1;
												}
											}
									  })
									: t._e(),
								t.isShowShapes
									? e('ShapePad', {
											attrs: { color: t.color, isMobile: !1 },
											on: {
												hide: function (e) {
													t.isShowShapes = !1;
												}
											}
									  })
									: t._e(),
								t.isShowLines
									? e('LinePad', {
											attrs: { color: t.color, isMobile: !1 },
											on: {
												hide: function (e) {
													t.isShowLines = !1;
												}
											}
									  })
									: t._e(),
								e('div', { staticClass: 'zoom-wrapper' }, [e('ZoomPad', { attrs: { isMobile: !1 } }), e('HistoryPad', { attrs: { isMobile: !1 } })], 1)
							],
							1
						);
					},
					a = [],
					c = i(3755),
					h = i(2668);
				const l = new c.UAParser(),
					u = 2,
					f = '#333333',
					d = 'rgba(255,255,255,0)',
					p = '#5C92EC',
					g = 4,
					v = 0.06,
					m = () => String(Math.round(1e18 * Math.random())),
					y = (t, e, i, n, r, o) => {
						(r = 'undefined' !== typeof r ? r : 30), (o = 'undefined' !== typeof r ? o : 10);
						const s = (180 * Math.atan2(e - n, t - i)) / Math.PI,
							a = ((s + r) * Math.PI) / 180,
							c = ((s - r) * Math.PI) / 180,
							h = o * Math.cos(a),
							l = o * Math.sin(a),
							u = o * Math.cos(c),
							f = o * Math.sin(c);
						let d = t - h,
							p = e - l,
							g = ' M ' + t + ' ' + e;
						return (g += ' L ' + i + ' ' + n), (d = i + h), (p = n + l), (g += ' M ' + d + ' ' + p), (g += ' L ' + i + ' ' + n), (d = i + u), (p = n + f), (g += ' L ' + d + ' ' + p), g;
					},
					b = l.getOS().name || '',
					x = l.getDevice().type || '',
					_ = ['mobile', 'tablet'].includes(x) || b.includes('Mobile') || h.Z.mobile() || h.Z.ipad(),
					w = (l.getBrowser().name, l.getBrowser().name, ['#333333', '#FFFFFF', '#00B4FF', '#FF2600', '#61ED00', '#FFEB02', '#8566FF', '#F32A9C', '#19ED9F']),
					{ EventEmitter: C, captureRejectionSymbol: S } = i(7187),
					T = ['pen', 'text', 'remove', 'line', 'arrow', 'dottedline', 'circle', 'ellipse', 'square', 'isosceles', 'rectangle', 'rightangle', 'equilateral'];
				class O extends C {
					constructor() {
						super({ captureRejections: !0 }),
							(this.drawType = ''),
							(this.drawWidth = u),
							(this.color = f),
							(this.textSize = 36),
							(this.colorset = !1),
							(this.lastDrawType = ''),
							(this.lastShape = 'circle'),
							(this.lastLine = 'line');
					}
					getOption() {
						return {
							drawType: this.drawType,
							drawWidth: this.drawWidth,
							color: this.color,
							textSize: this.textSize,
							colorset: this.colorset,
							lastShape: this.lastShape,
							lastLine: this.lastLine
						};
					}
					setDrawType(t, e = !0) {
						t !== this.drawType && ((this.drawType = t), t && e && (this.lastDrawType = t), this.emit('draw-type-chaged', { drawType: t }));
					}
					setShape(t) {
						this.lastShape = t;
					}
					setLine(t) {
						this.lastLine = t;
					}
					setDrawWidth(t) {
						t !== this.drawWidth && ((this.drawWidth = t), this.emit('draw-width-chaged', { drawWidth: t }));
					}
					setColor(t) {
						t !== this.color && ((this.color = t), this.emit('draw-color-chaged', { color: t }));
					}
					setTextSize(t) {
						t !== this.textSize && ((this.textSize = t), this.emit('text-size-chaged', { textSize: t }));
					}
					zoomout() {
						this.emit('zoomout');
					}
					zoomin() {
						this.emit('zoomin');
					}
					undo() {
						this.emit('undo');
					}
					redo() {
						this.emit('redo');
					}
					setZoom(t) {
						this.emit('zoom', t);
					}
					isDrawType(t) {
						return T.includes(t);
					}
					isSelector(t) {
						return 'selector' === t;
					}
					isPan(t) {
						return 'pan' === t;
					}
					mouseDown() {
						this.emit('mousedown');
					}
					reset() {
						(this.drawType = 'pen'), (this.drawWidth = u), (this.color = '#FF0000'), (this.textSize = 36), (this.colorset = !1);
					}
					[S](t, e, ...i) {
						console.error('rejection happened for', e, 'with', t, ...i), this.destroy(t);
					}
					destroy(t) {
						console.error('captureRejectionSymbol : ', t);
					}
				}
				const k = new O();
				var P = k,
					E = function () {
						var t = this,
							e = t._self._c;
						return e(
							'div',
							{ class: t.isMobile ? 'color-pad-container mobile' : 'color-pad-container pc' },
							t._l(t.colors, function (i) {
								return e(
									'span',
									{
										key: i,
										class: i === t.color ? 'color-item-wrapper active' : 'color-item-wrapper',
										on: {
											click: function (e) {
												return t.setcolor(i);
											}
										}
									},
									[e('span', { staticClass: 'color-item', style: { backgroundColor: i, border: '#FFFFFF' === i ? '1px solid #999999' : '' } })]
								);
							}),
							0
						);
					},
					M = [],
					j = {
						props: { isMobile: { type: Boolean, default: !1 } },
						data() {
							return { color: '#333333', colors: w };
						},
						mounted() {
							const t = P.getOption();
							this.color = t.color;
						},
						methods: {
							setcolor(t) {
								(this.color = t), P.setColor(t), this.$emit('hide');
							}
						}
					},
					D = j,
					A = i(1001),
					F = (0, A.Z)(D, E, M, !1, null, 'cb90cd44', null),
					L = F.exports,
					I = function () {
						var t = this,
							e = t._self._c;
						return e('div', { class: t.isMobile ? 'line-pad-container mobile' : 'line-pad-container pc' }, [
							e('table', { attrs: { id: 'customers' } }, [
								e('tr', [
									e('td', { class: 'line' === t.drawType ? 'active' : '', attrs: { 'data-type': 'line' }, on: { click: e => t.select('line', e) } }, [
										e('i', { staticClass: 'icon-tools icon-line-black icon', attrs: { 'data-default': 'icon-tools icon-line-black' } })
									]),
									e('td', { class: 'arrow' === t.drawType ? 'active' : '', attrs: { 'data-type': 'arrow' }, on: { click: e => t.select('arrow', e) } }, [
										e('i', { staticClass: 'icon-tools icon-arrow-black icon', attrs: { 'data-default': 'icon-tools icon-arrow-black' } })
									]),
									e('td', { class: 'dottedline' === t.drawType ? 'active' : '', attrs: { 'data-type': 'dottedline' }, on: { click: e => t.select('dottedline', e) } }, [
										e('i', { staticClass: 'icon-tools icon-dottedline-black icon', attrs: { 'data-default': 'icon-tools icon-dottedline-black' } })
									])
								])
							])
						]);
					},
					R = [],
					B = {
						components: {},
						props: { color: { type: String, default: '' }, isMobile: { type: Boolean, default: !1 } },
						data() {
							return { drawType: 'line' };
						},
						watch: {},
						mounted() {
							const t = P.getOption();
							this.drawType = t.lastLine;
						},
						beforeDestroy() {},
						methods: {
							select(t, e) {
								(this.drawType = t), P.setDrawType(t), P.setLine(t), this.$emit('hide');
							}
						}
					},
					z = B,
					X = (0, A.Z)(z, I, R, !1, null, '5d0a8016', null),
					W = X.exports,
					Y = function () {
						var t = this,
							e = t._self._c;
						return e('div', { class: t.isMobile ? 'shape-pad-container mobile' : 'shape-pad-container pc' }, [
							e('table', { attrs: { id: 'customers' } }, [
								e('tr', [
									e('td', { class: 'circle' === t.drawType ? 'active' : '', attrs: { 'data-type': 'circle' }, on: { click: e => t.select('circle', e) } }, [
										e('i', { staticClass: 'icon-tools icon-circle-black icon', attrs: { 'data-default': 'icon-tools icon-circle-black' } })
									]),
									e('td', { class: 'ellipse' === t.drawType ? 'active' : '', attrs: { 'data-type': 'ellipse' }, on: { click: e => t.select('ellipse', e) } }, [
										e('i', { staticClass: 'icon-tools icon-ellipse-black icon', attrs: { 'data-default': 'icon-tools icon-ellipse-black' } })
									]),
									e('td', { class: 'square' === t.drawType ? 'active' : '', attrs: { 'data-type': 'square' }, on: { click: e => t.select('square', e) } }, [
										e('i', { staticClass: 'icon-tools icon-square-black icon', attrs: { 'data-default': 'icon-tools icon-square-black' } })
									]),
									e('td', { class: 'rectangle' === t.drawType ? 'active' : '', attrs: { 'data-type': 'rectangle' }, on: { click: e => t.select('rectangle', e) } }, [
										e('i', { staticClass: 'icon-tools icon-rectangle-black icon', attrs: { 'data-default': 'icon-tools icon-rectangle-black' } })
									])
								]),
								e('tr', [
									e('td', { class: 'rightangle' === t.drawType ? 'active' : '', attrs: { 'data-type': 'rightangle' }, on: { click: e => t.select('rightangle', e) } }, [
										e('i', { staticClass: 'icon-tools icon-rightangle-black icon', attrs: { 'data-default': 'icon-tools icon-rightangle-black' } })
									]),
									e('td', { class: 'equilateral' === t.drawType ? 'active' : '', attrs: { 'data-type': 'equilateral' }, on: { click: e => t.select('equilateral', e) } }, [
										e('i', { staticClass: 'icon-tools icon-equilateral-black icon', attrs: { 'data-default': 'icon-tools icon-equilateral-black' } })
									]),
									e('td', { class: 'isosceles' === t.drawType ? 'active' : '', attrs: { 'data-type': 'isosceles' }, on: { click: e => t.select('isosceles', e) } }, [
										e('i', { staticClass: 'icon-tools icon-isosceles-black icon', attrs: { 'data-default': 'icon-tools icon-isosceles-black' } })
									]),
									e('td')
								])
							])
						]);
					},
					H = [],
					G = {
						components: {},
						props: { color: { type: String, default: '' }, isMobile: { type: Boolean, default: !1 } },
						data() {
							return { drawType: 'circle' };
						},
						watch: {},
						mounted() {
							const t = P.getOption();
							this.drawType = t.lastShape;
						},
						beforeDestroy() {},
						methods: {
							select(t, e) {
								(this.drawType = t), P.setDrawType(t), P.setShape(t), this.$emit('hide');
							}
						}
					},
					U = G,
					N = (0, A.Z)(U, Y, H, !1, null, '2bff958c', null),
					V = N.exports,
					q = function () {
						var t = this,
							e = t._self._c;
						return e('div', { class: t.isMobile ? 'history-pad-container mobile' : 'history-pad-container pc' }, [
							e('div', { staticClass: 'button-wrapper', attrs: { 'data-type': 'undo' }, on: { click: t.undo } }, [
								e('i', {
									staticClass: 'icon-tools icon',
									class: t.enableUndo ? 'icon-undo-black' : 'icon-undo-disable',
									attrs: { id: 'undo', 'data-default': 'icon-tools icon-undo-black' }
								})
							]),
							e('div', { staticClass: 'button-wrapper', attrs: { 'data-type': 'redo' }, on: { click: t.redo } }, [
								e('i', {
									staticClass: 'icon-tools icon',
									class: t.enableRedo ? 'icon-redo-black' : 'icon-redo-disable',
									attrs: { id: 'redo', 'data-default': 'icon-tools icon-redo-black' }
								})
							])
						]);
					},
					K = [];
				i(7658);
				const { EventEmitter: Z, captureRejectionSymbol: J } = i(7187);
				class $ extends Z {
					constructor() {
						super({ captureRejections: !0 }),
							(this.canvas = null),
							(this.extraProps = ['selectable', 'editable']),
							(this.undoStack = []),
							(this.redoStack = []),
							(this.objectProps = {}),
							(this.textProps = {});
					}
					init(t) {
						this.canvas = t;
					}
					clearHistory() {
						(this.undoStack = []), (this.redoStack = []), this.emit('history:clear');
					}
					saveAction(t = 'added', e, i) {
						if (!(!e || (e.isEditing && i.includes('mouse')))) {
							if (Array.isArray(e)) {
								if (
									(e.map((t, i) => {
										t.remote && e.splice(i, 1);
									}),
									e && e.length <= 0)
								)
									return;
							} else if (e.remote) return;
							'modified' !== t ? (this.undoStack.push({ type: t, object: e }), this.emit('history:undo', { undo: this.undoStack })) : this.processModifiedAction(t, e, i);
						}
					}
					undo() {
						if (this.undoStack.length) {
							var t = this.undoStack.pop();
							if (t && t.type) {
								switch (t.type) {
									case 'added':
										t.object && (canvas.remove(t.object), this.emit('object:removed', [t.object.id]));
										break;
									case 'removed':
										t.object &&
											t.object.forEach(t => {
												canvas.add(t), this.emit('object:added', [t]);
											});
										break;
									case 'modified':
										this.processModifiedUndo(t.object);
										break;
									case 'text:editing':
										this.processTextUndo(t.object);
										break;
								}
								canvas.renderAll();
							}
							this.redoStack.push(t), this.emit('history:undo', { undo: this.undoStack }), this.emit('history:redo', { redo: this.redoStack });
						}
					}
					redo() {
						if (this.redoStack.length) {
							var t = this.redoStack.pop();
							if (t && t.type) {
								switch (t.type) {
									case 'added':
										t.object && (canvas.add(t.object), this.emit('object:added', [t.object]));
										break;
									case 'removed':
										if (t.object) {
											t.object.forEach(t => {
												canvas.remove(t);
											});
											const e = t.object.map(t => t.id);
											this.emit('object:removed', e);
										}
										break;
									case 'modified':
										this.processModifiedRedo(t.object);
										break;
									case 'text:editing':
										this.processTextRedo(t.object);
										break;
								}
								canvas.renderAll();
							}
							this.undoStack.push(t), this.emit('history:undo', { undo: this.undoStack }), this.emit('history:redo', { redo: this.redoStack });
						}
					}
					getObjectByName(t) {
						const e = canvas.getObjects();
						for (let i = 0, n = e.length; i < n; i++) if (e[i].id === t) return e[i];
						return null;
					}
					getObjectsByName(t) {
						if (!t || t.length <= 0) return null;
						const e = canvas.getObjects(),
							i = e.filter(e => t.includes(e.id));
						return i;
					}
					samePosition(t, e) {
						return !t || !e || (t.left === e.left && t.top === e.top);
					}
					sameText(t, e) {
						return !(t && e && t.text && e.text) || t.text === e.text;
					}
					processModifiedAction(t, e, i) {
						if (e)
							if ('mouse:down' === i) this.objectProps.oldStage = { left: e.left, top: e.top };
							else if ('mouse:up' === i) {
								if (((this.objectProps.newStage = { left: e.left, top: e.top }), this.samePosition(this.objectProps.newStage, this.objectProps.oldStage)))
									return void (this.objectProps = {});
								const i = e._objects ? e._objects.map(t => t.id) : [e.id],
									n = { objects: i, oldStage: this.objectProps.oldStage, newStage: this.objectProps.newStage };
								this.undoStack.push({ type: t, object: n }),
									this.emit('history:undo', { undo: this.undoStack }),
									this.emit('object:modified', { objects: i, state: this.objectProps.newStage }),
									(this.objectProps = {});
							} else if ('text:editing:entered' === i) this.textProps.oldStage = { text: e.text };
							else if ('text:editing:exited' === i) {
								if (((this.textProps.newStage = { text: e.text }), this.sameText(this.textProps.newStage, this.textProps.oldStage))) return void (this.textProps = {});
								const t = { objectId: e.id, oldStage: this.textProps.oldStage, newStage: this.textProps.newStage };
								this.undoStack.push({ type: 'text:editing', object: t }), this.emit('history:undo', { undo: this.undoStack });
							}
					}
					processModifiedUndo(t) {
						if (!t || !t.objects || t.objects.length <= 0) return;
						const e = this.getObjectsByName(t.objects);
						canvas.discardActiveObject();
						const i = new fabric.ActiveSelection(e, { canvas: canvas });
						if (i) {
							for (var n in t.oldStage) i.set(n, t.oldStage[n]);
							this.emit('object:modified', { objects: t.objects, state: t.oldStage });
						} else console.warn('processModifiedUndo : ', t);
						canvas.discardActiveObject();
					}
					processModifiedRedo(t) {
						if (!t || !t.objects || t.objects.length <= 0) return;
						const e = this.getObjectsByName(t.objects);
						canvas.discardActiveObject();
						const i = new fabric.ActiveSelection(e, { canvas: canvas });
						if (i) {
							for (var n in t.newStage) i.set(n, t.newStage[n]);
							this.emit('object:modified', { objects: t.objects, state: t.newStage });
						} else console.warn('processModifiedRedo : ', t);
						canvas.discardActiveObject();
					}
					processTextUndo(t) {
						if (!t) return;
						const e = this.getObjectByName(t.objectId);
						if (e) for (var i in t.oldStage) e.set(i, t.oldStage[i]);
					}
					processTextRedo(t) {
						if (!t) return;
						const e = this.getObjectByName(t.objectId);
						if (e) for (var i in t.newStage) e.set(i, t.newStage[i]);
					}
					[J](t, e, ...i) {
						console.error('rejection happened for', e, 'with', t, ...i), this.destroy(t);
					}
					destroy(t) {
						console.error('captureRejectionSymbol : ', t);
					}
				}
				const Q = new $();
				var tt = Q,
					et = {
						props: { isMobile: { type: Boolean, default: !1 } },
						data() {
							return { enableUndo: !1, enableRedo: !1 };
						},
						mounted() {
							tt.on('history:undo', t => {
								t && t.undo && t.undo.length > 0 ? (this.enableUndo = !0) : (this.enableUndo = !1);
							}),
								tt.on('history:redo', t => {
									t && t.redo && t.redo.length > 0 ? (this.enableRedo = !0) : (this.enableRedo = !1);
								});
						},
						methods: {
							undo() {
								P.undo();
							},
							redo() {
								P.redo();
							}
						}
					},
					it = et,
					nt = (0, A.Z)(it, q, K, !1, null, '4007e0d3', null),
					rt = nt.exports,
					ot = function () {
						var t = this,
							e = t._self._c;
						return e('div', { class: t.isMobile ? 'zoom-pad-container mobile' : 'zoom-pad-container pc' }, [
							e('span', { staticClass: 'button', class: t.zoom > t.zoomMin ? '' : 'disable', on: { click: t.zoomout } }, [e('i', { staticClass: 'zoomout icon' })]),
							e('span', { staticClass: 'button', class: t.zoom < t.zoomMax ? '' : ' disable', on: { click: t.zoomin } }, [e('i', { staticClass: 'zoomin icon' })]),
							e('span', { staticClass: 'label' }, [t._v(t._s(Math.round(100 * this.zoom) + '%'))])
						]);
					},
					st = [],
					at = {
						props: { isMobile: { type: Boolean, default: !1 } },
						data() {
							return { zoom: 1, zoomMax: g, zoomMin: v };
						},
						mounted() {
							P.on('zoom', t => {
								this.zoom = t;
							});
						},
						methods: {
							zoomin() {
								P.zoomin();
							},
							zoomout() {
								P.zoomout();
							}
						}
					},
					ct = at,
					ht = (0, A.Z)(ct, ot, st, !1, null, '623b0440', null),
					lt = ht.exports,
					ut = {
						components: { ColorPad: L, LinePad: W, ShapePad: V, HistoryPad: rt, ZoomPad: lt },
						name: 'ToolBar',
						props: {},
						data() {
							return { drawType: 'selector', drawWidth: 2, color: '#FF0000', isShowColor: !1, textSize: 36, isShowLines: !1, isShowShapes: !1, isTextCreate: !1 };
						},
						mounted() {
							const t = P.getOption();
							(this.drawType = t.drawType),
								(this.drawWidth = t.drawWidth),
								(this.color = t.color),
								(this.activeButton = t.drawType),
								(this.textSize = t.textSize),
								P.on('draw-type-chaged', t => {
									(this.drawType = t.drawType), 'text' !== this.drawType && (this.isTextCreate = !1);
								}),
								P.on('draw-color-chaged', t => {
									this.color = t.color;
								}),
								P.on('mousedown', t => {
									(this.isShowLines = !1), (this.isShowShapes = !1), (this.isShowColor = !1), 'text' === this.drawType && (this.isTextCreate = !0);
								});
						},
						beforeDestroy() {
							P.reset();
						},
						methods: {
							changeColor() {
								(this.isShowLines = !1), (this.isShowShapes = !1), (this.isShowColor = !this.isShowColor);
							},
							select(t, e) {
								(this.isShowLines = !1), (this.isShowShapes = !1), (this.isShowColor = !1);
								const i = ['pen', 'text', 'remove'];
								t === this.drawType && i.includes(t)
									? 'text' === t && this.isTextCreate
										? ((this.drawType = 'selector'), P.setDrawType('selector'), (this.drawType = 'text'), P.setDrawType('text'))
										: ((this.drawType = 'selector'), P.setDrawType('selector'))
									: t === this.drawType && 'selector' === t
									? ((this.drawType = 'pan'), P.setDrawType('pan'))
									: ((this.drawType = t), P.setDrawType(t));
							},
							zoomout() {
								P.zoomout(), (this.isShowColor = !1);
							},
							zoomin() {
								P.zoomin(), (this.isShowColor = !1);
							},
							shapes() {
								if (((this.isShowLines = !1), (this.isShowColor = !1), (this.isShowShapes = !this.isShowShapes), this.isShowShapes)) {
									const t = P.getOption();
									(this.drawType = t.lastShape), P.setDrawType(this.drawType);
								} else P.setDrawType('selector');
							},
							lines() {
								if (((this.isShowShapes = !1), (this.isShowColor = !1), (this.isShowLines = !this.isShowLines), this.isShowLines)) {
									const t = P.getOption();
									(this.drawType = t.lastLine), P.setDrawType(this.drawType);
								} else P.setDrawType('selector');
							},
							isLineType() {
								const t = ['line', 'arrow', 'dottedline'];
								return t.includes(this.drawType);
							},
							isShapeType() {
								const t = ['circle', 'ellipse', 'square', 'isosceles', 'rectangle', 'rightangle', 'equilateral'];
								return t.includes(this.drawType);
							}
						}
					},
					ft = ut,
					dt = (0, A.Z)(ft, s, a, !1, null, '006fda46', null),
					pt = dt.exports,
					gt = function () {
						var t = this,
							e = t._self._c;
						return e(
							'div',
							{ directives: [{ name: 'show', rawName: 'v-show', value: !t.isKeyboardShow, expression: '!isKeyboardShow' }], staticClass: 'toolbar-container' },
							[
								e('ul', { directives: [{ name: 'show', rawName: 'v-show', value: !t.isHideToolbar, expression: '!isHideToolbar' }], staticClass: 'tools', attrs: { id: 'toolsul' } }, [
									e('li', { class: 'pan' === t.drawType ? 'active' : '', attrs: { id: 'pointer-select', 'data-type': 'pointer' }, on: { click: e => t.select('pan', e) } }, [
										e('i', { staticClass: 'icon-tools icon-pan-black icon', attrs: { 'data-default': 'icon-tools icon-pan-black icon' } })
									]),
									e('li', { attrs: { id: 'color-select', 'data-type': 'color' }, on: { click: t.changeColor } }, [
										e('i', {
											staticClass: 'icon-tools icon-color-black',
											style: { backgroundColor: t.color, border: '#FFFFFF' === t.color ? '1px solid #999999' : '' },
											attrs: { 'data-default': 'icon-tools icon-color-black' }
										})
									]),
									e('li', { class: 'pen' === t.drawType ? 'active' : '', attrs: { id: 'toolsPencil', 'data-type': 'pen' }, on: { click: e => t.select('pen', e) } }, [
										e('i', { staticClass: 'icon-tools icon-pen-black icon', attrs: { 'data-default': 'icon-tools icon-pen-black icon' } })
									]),
									e('li', { class: t.isLineType() ? 'active' : '', attrs: { 'data-type': 'lines' }, on: { click: t.lines } }, [
										e('i', { staticClass: 'icon-tools icon-lines-black icon', attrs: { id: 'lines', 'data-default': 'icon-tools icon-lines-black' } })
									]),
									e('li', { class: t.isShapeType() ? 'active' : '', attrs: { 'data-type': 'shape' }, on: { click: t.shapes } }, [
										e('i', { staticClass: 'icon-tools icon-shape-black icon', attrs: { id: 'shape', 'data-default': 'icon-tools icon-shape-black' } })
									]),
									e('li', { class: 'text' !== t.drawType || t.isTextCreate ? '' : 'active', attrs: { 'data-type': 'text' }, on: { click: e => t.select('text', e) } }, [
										e('i', { staticClass: 'icon-tools icon-text-black icon', attrs: { 'data-default': 'icon-tools icon-text-black' } })
									]),
									e('li', { class: 'remove' === t.drawType ? 'active' : '', attrs: { 'data-type': 'remove' }, on: { click: e => t.select('remove', e) } }, [
										e('i', { staticClass: 'icon-tools icon-remove-black icon', attrs: { 'data-default': 'icon-tools icon-remove-black' } })
									]),
									e('li', { attrs: { 'data-type': 'hide' }, on: { click: t.hideToolbar } }, [
										e('i', { staticClass: 'icon-tools icon-hide-black icon', attrs: { id: 'hide', 'data-default': 'icon-tools icon-hide-black' } })
									])
								]),
								e(
									'div',
									{
										directives: [{ name: 'show', rawName: 'v-show', value: t.isHideToolbar, expression: 'isHideToolbar' }],
										staticClass: 'button-wrapper',
										on: {
											click: function (e) {
												t.isHideToolbar = !1;
											}
										}
									},
									[e('i', { staticClass: 'icon-tools icon-show-black icon', attrs: { id: 'show', 'data-default': 'icon-tools icon-show-black' } })]
								),
								t.isShowColor
									? e('ColorPad', {
											attrs: { isMobile: !0 },
											on: {
												hide: function (e) {
													t.isShowColor = !1;
												}
											}
									  })
									: t._e(),
								t.isShowShapes
									? e('ShapePad', {
											attrs: { color: t.color, isMobile: !0 },
											on: {
												hide: function (e) {
													t.isShowShapes = !1;
												}
											}
									  })
									: t._e(),
								t.isShowLines
									? e('LinePad', {
											attrs: { color: t.color, isMobile: !0 },
											on: {
												hide: function (e) {
													t.isShowLines = !1;
												}
											}
									  })
									: t._e(),
								e('ZoomMark'),
								e('HistoryPad', { attrs: { isMobile: !0 } })
							],
							1
						);
					},
					vt = [],
					mt = function () {
						var t = this,
							e = t._self._c;
						return e('div', { staticClass: 'zoom-mark-container', style: { visibility: t.hide ? 'hidden' : 'visible' } }, [
							e('span', { staticClass: 'label' }, [t._v(t._s(Math.round(100 * this.zoom) + '%'))])
						]);
					},
					yt = [],
					bt = {
						props: {},
						data() {
							return { zoom: 1, timer: null, hide: !0 };
						},
						mounted() {
							P.on('zoom', t => {
								(this.hide = !1), (this.zoom = t), clearTimeout(this.timer);
								const e = this;
								this.timer = setTimeout(() => {
									e.hide = !0;
								}, 1e3);
							});
						},
						methods: {}
					},
					xt = bt,
					_t = (0, A.Z)(xt, mt, yt, !1, null, 'd814a814', null),
					wt = _t.exports,
					Ct = {
						components: { ColorPad: L, LinePad: W, ShapePad: V, HistoryPad: rt, ZoomMark: wt },
						name: 'ToolBar',
						props: { offsetTop: { type: Number, default: 0 } },
						data() {
							return {
								drawType: 'pan',
								drawWidth: 2,
								color: '#FF0000',
								activeButton: 'pen',
								textSize: 36,
								isShowLines: !1,
								isShowShapes: !1,
								isHideToolbar: !1,
								isShowColor: !1,
								isTextCreate: !1,
								isKeyboardShow: !1
							};
						},
						watch: {
							offsetTop(t, e) {
								t !== e && (this.isKeyboardShow = t < 0);
							}
						},
						mounted() {
							const t = P.getOption();
							(this.drawType = t.drawType),
								(this.drawWidth = t.drawWidth),
								(this.color = t.color),
								(this.activeButton = t.drawType),
								(this.textSize = t.textSize),
								P.on('draw-type-chaged', t => {
									this.drawType = t.drawType;
								}),
								P.on('draw-color-chaged', t => {
									this.color = t.color;
								}),
								P.on('mousedown', t => {
									(this.isShowLines = !1), (this.isShowShapes = !1), (this.isShowColor = !1), 'text' === this.drawType && (this.isTextCreate = !0);
								});
						},
						beforeDestroy() {
							P.reset();
						},
						methods: {
							changeColor() {
								(this.isShowLines = !1), (this.isShowShapes = !1), (this.isShowColor = !this.isShowColor);
							},
							select(t, e) {
								(this.isShowLines = !1), (this.isShowShapes = !1), (this.isShowColor = !1), (this.isTextCreate = !1);
								const i = ['pen', 'text', 'remove'];
								t === this.drawType && i.includes(t)
									? ((this.drawType = 'pan'), P.setDrawType('pan'))
									: t === this.drawType && 'pan' === t
									? ((this.drawType = 'selector'), P.setDrawType('selector'))
									: ((this.drawType = t), P.setDrawType(t));
							},
							shapes() {
								if (((this.isShowLines = !1), (this.isShowColor = !1), (this.isShowShapes = !this.isShowShapes), this.isShowShapes)) {
									const t = P.getOption();
									(this.drawType = t.lastShape), P.setDrawType(this.drawType);
								} else P.setDrawType('pan');
							},
							lines() {
								if (((this.isShowShapes = !1), (this.isShowColor = !1), (this.isShowLines = !this.isShowLines), this.isShowLines)) {
									const t = P.getOption();
									(this.drawType = t.lastLine), P.setDrawType(this.drawType);
								} else P.setDrawType('pan');
							},
							isLineType() {
								const t = ['line', 'arrow', 'dottedline'];
								return t.includes(this.drawType);
							},
							isShapeType() {
								const t = ['circle', 'ellipse', 'square', 'isosceles', 'rectangle', 'rightangle', 'equilateral'];
								return t.includes(this.drawType);
							},
							hideToolbar() {
								(this.isHideToolbar = !0), (this.isShowLines = !1), (this.isShowShapes = !1), (this.isShowColor = !1);
							}
						}
					},
					St = Ct,
					Tt = (0, A.Z)(St, gt, vt, !1, null, '24a0a064', null),
					Ot = Tt.exports,
					kt = function () {
						var t = this;
						t._self._c;
						return t._m(0);
					},
					Pt = [
						function () {
							var t = this,
								e = t._self._c;
							return e('div', { staticClass: 'white-board-container' }, [
								e('div', { staticClass: 'canvasDiv', attrs: { id: 'canvasDiv' } }, [
									e('canvas', { staticClass: 'pc-box', attrs: { id: 'c' } }, [t._v(' lease use the browser support HTML5 ')])
								])
							]);
						}
					];
				const Et = i(9285).fabric;
				var Mt = {
						props: { offsetTop: { type: Number, default: 0 } },
						data() {
							return {
								mouseFrom: {},
								mouseTo: {},
								drawType: 'selector',
								textbox: null,
								color: 'black',
								drawingObject: null,
								moveCount: 1,
								doDrawing: !1,
								zoom: 1,
								isMoving: !1,
								editingTextbox: null
							};
						},
						watch: {
							offsetTop(t, e) {
								if (!_ || t === e) return;
								const i = this.textbox || this.editingTextbox;
								if (((this.textbox && !i.text) || (this.editingTextbox && i.text)) && Math.abs(t) > 200) {
									const e = document.documentElement.clientHeight - i.top - 30;
									if (e < Math.abs(t)) {
										const i = document.getElementById('app');
										i.style.transform = `translate(0, ${t + e - 50}px)`;
									}
								}
								if (0 === t) {
									const t = document.getElementById('app');
									if (((t.style.transform = 'translate(0, 0)'), i)) {
										i.exitEditing();
										let t = i.text;
										'string' !== typeof t && (t = i.text.join('')),
											t.trim() || this.canvas.remove(i),
											(this.textbox = null),
											(this.editingTextbox = null),
											this.$nextTick(() => {
												this.canvas.discardActiveObject(), P.setDrawType('pan');
											});
									}
								}
							}
						},
						mounted() {
							this.initDrawoption(),
								this.init(),
								this.notifyLoad(),
								this.notifyUpdate({ status: 'ready' }),
								document.body.addEventListener(
									'touchmove',
									function (t) {
										t.preventDefault();
									},
									{ passive: !1 }
								),
								_ ? P.setDrawType('pan') : P.setDrawType('selector'),
								this.initHistoryListen();
						},
						methods: {
							initDrawoption() {
								const t = P.getOption();
								(this.drawType = t.drawType),
									(this.drawWidth = t.drawWidth),
									(this.color = t.color),
									(this.colorset = t.colorset),
									(this.textSize = t.textSize),
									P.on('draw-type-chaged', t => {
										(this.drawType = t.drawType),
											(this.canvas.isDrawingMode = !1),
											(this.canvas.defaultCursor = 'default'),
											(this.canvas.hoverCursor = 'move'),
											this.canvas.discardActiveObject(),
											this.textbox && (this.textbox.exitEditing(), (this.textbox = null)),
											'pen' === this.drawType
												? ((this.canvas.isDrawingMode = !0), this.disableSelector(), (this.canvas.freeDrawingCursor = "url('./assets/img/cursor-pen.png') 6 20, auto"))
												: 'remove' === this.drawType
												? (this.enableSelector(),
												  this.canvas.discardActiveObject(),
												  (this.canvas.selection = !0),
												  (this.canvas.skipTargetFind = !1),
												  (this.canvas.selectable = !0),
												  (this.canvas.defaultCursor = "url('./assets/img/cursor-eraser.png') 6 15, auto"),
												  (this.canvas.hoverCursor = "url('./assets/img/cursor-eraser.png') 6 15, auto"))
												: 'selector' === this.drawType
												? ((this.canvas.defaultCursor = "url('./assets/img/cursor-selector.png') 10 5, auto"), this.enableSelector(), (this.canvas.selection = !0))
												: 'pan' === this.drawType
												? (_ ? this.enableSelector() : this.disableSelector(),
												  (this.canvas.selection = !1),
												  (this.canvas.defaultCursor = 'grab'),
												  (this.canvas.hoverCursor = 'grab'))
												: ((this.canvas.skipTargetFind = !0),
												  (this.canvas.selection = !1),
												  this.disableSelector(),
												  'text' === this.drawType ? (this.canvas.defaultCursor = 'text') : (this.canvas.defaultCursor = 'crosshair')),
											this.drawType || (this.enableSelector(), (this.canvas.selection = !0)),
											this.canvas.requestRenderAll();
									}),
									P.on('draw-color-chaged', t => {
										(this.color = t.color), (this.canvas.freeDrawingBrush.color = this.color);
									}),
									P.on('text-size-chaged', t => {
										this.textSize = t.textSize;
									}),
									P.on('zoomout', t => {
										this.zoomout();
									}),
									P.on('zoomin', t => {
										this.zoomin();
									}),
									P.on('undo', t => {
										this.undo();
									}),
									P.on('redo', t => {
										this.redo();
									});
							},
							init() {
								(this.canvas = new Et.Canvas('c', { isDrawingMode: !0, skipTargetFind: !0, selection: !1, hasControls: !1 })), tt.init(this.canvas);
								const t = document.documentElement.clientWidth,
									e = document.documentElement.clientHeight;
								this.canvas.setHeight(e),
									this.canvas.setWidth(t),
									(this.zoom = 1),
									(this.canvas.freeDrawingBrush.color = this.color),
									(this.canvas.freeDrawingBrush.width = u),
									this.onMouseDown(),
									this.onMouseUp(),
									this.onMouseMove(),
									this.onSelectionCreated(),
									this.onModified(),
									this.onTextEdit(),
									_ ? this.onGesture() : (this.onMouseWheel(), this.onKeyEvent()),
									(window.canvas = this.canvas),
									(window.zoom = window.zoom ? window.zoom : this.zoom);
								const i = this;
								window.onUpdate = t => {
									i.onUpdate(t);
								};
							},
							onMouseDown() {
								this.canvas.on('mouse:down', t => {
									P.mouseDown();
									const e = this.transformMouse(t.e);
									(this.mouseFrom.x = e.x),
										(this.mouseFrom.y = e.y),
										'pan' === this.drawType ? (this.panning = !0) : this.drawType && (this.doDrawing = !0),
										_ &&
											('pan' === P.lastDrawType && (this.canvas.getActiveObject() ? P.setDrawType('selector', !1) : (P.setDrawType('pan'), (this.panning = !0))),
											(this.panLast = this.mouseFrom)),
										(this.isMoving = !1),
										tt.saveAction('modified', t.target, 'mouse:down');
								});
							},
							onMouseUp() {
								this.canvas.on('mouse:up', t => {
									if (('selector' === this.drawType && tt.saveAction('modified', t.target, 'mouse:up'), (this.panning = !1), 'mouseup' === t.e.type)) {
										const e = this.transformMouse(t.e);
										(this.mouseTo.x = e.x), (this.mouseTo.y = e.y);
									}
									(this.isMoving || ['text', 'remove'].includes(this.drawType)) && this.drawing('mouse:up');
									const e = _ ? ['pen', 'text', 'remove', 'selector'] : ['pen', 'text', 'remove', 'pan'];
									if (
										(_
											? (e.includes(this.drawType) || P.setDrawType('pan'), 'pan' !== P.lastDrawType || this.canvas.getActiveObject() || P.setDrawType('pan'))
											: (e.includes(this.drawType) || P.setDrawType('selector'),
											  'pan' === this.drawType || 'selector' !== P.lastDrawType || this.canvas.getActiveObject() || P.setDrawType('selector')),
										(this.drawingObject = null),
										(this.moveCount = 1),
										(this.doDrawing = !1),
										this.canvas.isDrawingMode)
									) {
										const t = this.canvas.getObjects()[canvas.getObjects().length - 1];
										t && !t.id && (t.id = m()),
											t && (this.notifyUpdate({ drawType: 'pen', id: t.id, color: this.color, object: JSON.stringify(t), renew: !0 }), tt.saveAction('added', t));
									}
								});
							},
							onMouseMove() {
								this.canvas.on('mouse:move', t => {
									if (this.doDrawing || this.panning) {
										if (this.panning && 'pan' === this.drawType && !_) {
											const e = new Et.Point(t.e.movementX, t.e.movementY);
											this.canvas.relativePan(e);
										} else if ((this.moveCount++, this.moveCount % 10 === 0)) {
											const e = this.transformMouse(t.e);
											(this.mouseTo.x = e.x), (this.mouseTo.y = e.y), this.drawing();
										}
										this.isMoving = !0;
									}
								});
							},
							onMouseWheel() {
								const t = this;
								this.canvas.on('mouse:wheel', function (e) {
									if (e.e.ctrlKey || e.e.metaKey) {
										const i = e.e.deltaY;
										let n = t.canvas.getZoom();
										n *= 0.999 ** i;
										const r = new Et.Point(e.e.x, e.e.y);
										t.zoomToPoint(r, n), e.e.preventDefault(), e.e.stopPropagation();
									} else if (!t.textbox) {
										const i = new Et.Point(0, -e.e.deltaY);
										t.canvas.relativePan(i);
									}
								});
							},
							onSelectionCreated() {
								this.canvas.on('selection:created', t => {
									if ('remove' === this.drawType) {
										t.selected.forEach(t => {
											this.canvas.remove(t);
										}),
											this.canvas.discardActiveObject(),
											tt.saveAction('removed', t.selected);
										const e = t.selected.map(t => t.id);
										this.notifyUpdate({ drawType: 'object:removed', value: e });
									}
								});
							},
							onModified() {
								this.canvas.on('object:modified', t => {
									t.target.text && this.notifyUpdate({ drawType: 'text', id: t.target.id, color: this.color, text: t.target.text });
								});
							},
							onKeyEvent() {
								const t = this;
								(document.onkeydown = function (e) {
									t.textbox ||
										('Space' === e.code
											? P.setDrawType('pan', !1)
											: 'KeyZ' === e.code && (e.ctrlKey || e.metaKey) && e.shiftKey
											? P.redo()
											: 'KeyZ' === e.code && (e.ctrlKey || e.metaKey) && P.undo());
								}),
									(document.onkeyup = function (e) {
										t.textbox || ('Space' === e.code && P.setDrawType(P.lastDrawType));
									});
							},
							onTextEdit() {
								const t = this;
								this.canvas.on('text:editing:entered', e => {
									(t.editingTextbox = e.target), tt.saveAction('modified', e.target, 'text:editing:entered');
								}),
									this.canvas.on('text:editing:exited', e => {
										tt.saveAction('modified', e.target, 'text:editing:exited'), (t.editingTextbox = null);
										let i = e.target.text;
										'string' !== typeof i && (i = i.join('')),
											i.trim() ||
												this.$nextTick(() => {
													canvas.remove(e.target);
												}),
											'text' === t.drawType &&
												(t.$nextTick(() => {
													_ ? P.setDrawType('pan') : t.textbox && P.setDrawType('selector');
												}),
												tt.saveAction('added', e.target));
									});
							},
							onGesture() {
								const t = this;
								(this.panLast = { x: 0, y: 0 }),
									this.canvas.on({
										'touch:gesture': function (e) {
											if (e.e.touches && 2 == e.e.touches.length) {
												t.panning = !1;
												const i = new Et.Point(e.self.x, e.self.y);
												'start' == e.self.state && (t.zoomStartScale = t.canvas.getZoom());
												const n = t.zoomStartScale * e.self.scale;
												t.zoomToPoint(i, n),
													t.$nextTick(() => {
														t.panning = !0;
													});
											}
										}
									}),
									this.canvas.on('touch:drag', e => {
										if ((this.doDrawing || this.panning) && this.panning && 'pan' === this.drawType && this.isMoving) {
											const n = e.self.x,
												r = e.self.y,
												o = n - t.panLast.x,
												s = r - t.panLast.y;
											if (Math.abs(n - t.panLast.x) <= 50 && Math.abs(r - t.panLast.y) <= 50) {
												var i = new Et.Point(o, s);
												canvas.relativePan(i);
											}
											(t.panLast.x = e.self.x), (t.panLast.y = e.self.y);
										}
									}),
									this.canvas.on('touch:longpress', e => {
										'pan' === t.drawType && P.setDrawType('selector', !1);
									});
							},
							notifyUpdate(t) {
								this.notifyMsg({ method: 'update', data: JSON.stringify(t) });
							},
							notifyMsg(t) {
								if (window.notifyMsg) window.notifyMsg(JSON.stringify(t));
								else
									try {
										parent[frameElement.getAttribute('id')](JSON.stringify(t));
									} catch (e) {
										console.warn('notifyMsg error : ', e);
									}
							},
							drawing(t = '') {
								this.drawingObject && (canvas.remove(this.drawingObject), this.notifyUpdate({ drawType: 'object:removed', value: [this.drawingObject.id] }));
								let e,
									i,
									n,
									r,
									o,
									s,
									a = null;
								switch (this.drawType) {
									case 'arrow':
										a = new Et.Path(y(this.mouseFrom.x, this.mouseFrom.y, this.mouseTo.x, this.mouseTo.y, 30, 30), { stroke: this.color, fill: d, strokeWidth: u });
										break;
									case 'line':
										a = new Et.Line([this.mouseFrom.x, this.mouseFrom.y, this.mouseTo.x, this.mouseTo.y], { stroke: this.color, strokeWidth: u });
										break;
									case 'dottedline':
										a = new Et.Line([this.mouseFrom.x, this.mouseFrom.y, this.mouseTo.x, this.mouseTo.y], { strokeDashArray: [3, 1], stroke: this.color, strokeWidth: u });
										break;
									case 'circle':
										(e = this.mouseFrom.x),
											(i = this.mouseFrom.y),
											(n = Math.sqrt((this.mouseTo.x - e) * (this.mouseTo.x - e) + (this.mouseTo.y - i) * (this.mouseTo.y - i)) / 2),
											(a = new Et.Circle({ left: e, top: i, stroke: this.color, fill: d, radius: n, strokeWidth: u }));
										break;
									case 'ellipse':
										(e = this.mouseFrom.x),
											(i = this.mouseFrom.y),
											(n = Math.sqrt((this.mouseTo.x - e) * (this.mouseTo.x - e) + (this.mouseTo.y - i) * (this.mouseTo.y - i)) / 2),
											(a = new Et.Ellipse({
												left: e,
												top: i,
												stroke: this.color,
												fill: d,
												originX: 'center',
												originY: 'center',
												rx: Math.abs(e - this.mouseTo.x),
												ry: Math.abs(i - this.mouseTo.y),
												strokeWidth: u
											}));
										break;
									case 'square':
										a = new Et.Rect({
											left: this.mouseFrom.x,
											top: this.mouseFrom.y,
											fill: d,
											stroke: this.color,
											strokeWidth: u,
											width: Math.max(this.mouseTo.x - this.mouseFrom.x, this.mouseTo.y - this.mouseFrom.y),
											height: Math.max(this.mouseTo.x - this.mouseFrom.x, this.mouseTo.y - this.mouseFrom.y)
										});
										break;
									case 'rectangle':
										(s =
											'M ' +
											this.mouseFrom.x +
											' ' +
											this.mouseFrom.y +
											' L ' +
											this.mouseTo.x +
											' ' +
											this.mouseFrom.y +
											' L ' +
											this.mouseTo.x +
											' ' +
											this.mouseTo.y +
											' L ' +
											this.mouseFrom.x +
											' ' +
											this.mouseTo.y +
											' L ' +
											this.mouseFrom.x +
											' ' +
											this.mouseFrom.y +
											' z'),
											(a = new Et.Path(s, { left: e, top: i, stroke: this.color, strokeWidth: u, fill: d }));
										break;
									case 'rightangle':
										(s = 'M ' + this.mouseFrom.x + ' ' + this.mouseFrom.y + ' L ' + this.mouseFrom.x + ' ' + this.mouseTo.y + ' L ' + this.mouseTo.x + ' ' + this.mouseTo.y + ' z'),
											(a = new Et.Path(s, { left: e, top: i, stroke: this.color, strokeWidth: u, fill: d }));
										break;
									case 'equilateral':
										(o = this.mouseTo.y - this.mouseFrom.y),
											(a = new Et.Triangle({
												top: this.mouseFrom.y,
												left: this.mouseFrom.x,
												width: Math.sqrt(Math.pow(o, 2) + Math.pow(o / 2, 2)),
												height: o,
												stroke: this.color,
												strokeWidth: u,
												fill: d
											}));
										break;
									case 'isosceles':
										(r = this.mouseTo.x - this.mouseFrom.x),
											(o = this.mouseTo.y - this.mouseFrom.y),
											(a = new Et.Triangle({ top: this.mouseFrom.y, left: this.mouseFrom.x, width: r, height: o, stroke: this.color, strokeWidth: u, fill: d }));
										break;
									case 'text':
										(this.textbox = new Et.Textbox('', {
											left: this.mouseFrom.x - 0,
											top: this.mouseFrom.y - 20,
											width: 150,
											fontSize: 30,
											borderColor: p,
											fill: this.color,
											hasControls: !1
										})),
											(this.textbox.id = m()),
											notifyUpdate({ drawType: this.drawType, mouseFrom: this.mouseFrom, color: this.color, id: this.textbox.id, renew: !0 }),
											this.canvas.add(this.textbox),
											this.textbox.enterEditing(),
											this.textbox.hiddenTextarea.focus(),
											this.canvas.setActiveObject(this.textbox);
										break;
									case 'remove':
										break;
									case 'zoomout':
										console.warn('zoomout');
										break;
									case 'zoomin':
										console.warn('zoomin');
										break;
									default:
										break;
								}
								a &&
									((a.id = m()),
									this.canvas.add(a),
									this.notifyUpdate({ drawType: this.drawType, mouseFrom: this.mouseFrom, mouseTo: this.mouseTo, color: this.color, id: a.id, renew: !0 }),
									(this.drawingObject = a),
									'mouse:up' === t && tt.saveAction('added', a));
							},
							transformMouse(t) {
								return t ? this.canvas.getPointer(t) : { x: 0, y: 0 };
							},
							onUpdate(t) {
								const e = JSON.parse(t),
									i = e.drawType,
									n = e.mouseFrom,
									r = e.mouseTo;
								let o,
									s,
									a,
									c,
									h,
									l = null,
									f = '';
								switch (i) {
									case 'arrow':
										l = new Et.Path(y(n.x, n.y, r.x, r.y, 30, 30), { stroke: e.color, fill: d, strokeWidth: u });
										break;
									case 'line':
										l = new Et.Line([n.x, n.y, r.x, r.y], { stroke: e.color, strokeWidth: u });
										break;
									case 'dottedline':
										l = new Et.Line([n.x, n.y, r.x, r.y], { strokeDashArray: [3, 1], stroke: e.color, strokeWidth: u });
										break;
									case 'circle':
										(o = n.x),
											(s = n.y),
											(a = Math.sqrt((r.x - o) * (r.x - o) + (r.y - s) * (r.y - s)) / 2),
											(l = new Et.Circle({ left: o, top: s, stroke: e.color, fill: d, radius: a, strokeWidth: u }));
										break;
									case 'ellipse':
										(o = n.x),
											(s = n.y),
											(a = Math.sqrt((r.x - o) * (r.x - o) + (r.y - s) * (r.y - s)) / 2),
											(l = new Et.Ellipse({
												left: o,
												top: s,
												stroke: e.color,
												fill: d,
												originX: 'center',
												originY: 'center',
												rx: Math.abs(o - r.x),
												ry: Math.abs(s - r.y),
												strokeWidth: u
											}));
										break;
									case 'square':
										l = new Et.Rect({
											left: n.x,
											top: n.y,
											fill: d,
											stroke: e.color,
											strokeWidth: u,
											width: Math.max(r.x - n.x, r.y - n.y),
											height: Math.max(r.x - n.x, r.y - n.y)
										});
										break;
									case 'rectangle':
										(f = 'M ' + n.x + ' ' + n.y + ' L ' + r.x + ' ' + n.y + ' L ' + r.x + ' ' + r.y + ' L ' + n.x + ' ' + r.y + ' L ' + n.x + ' ' + n.y + ' z'),
											(l = new Et.Path(f, { left: o, top: s, stroke: e.color, strokeWidth: u, fill: d }));
										break;
									case 'rightangle':
										(f = 'M ' + n.x + ' ' + n.y + ' L ' + n.x + ' ' + r.y + ' L ' + r.x + ' ' + r.y + ' z'),
											(l = new Et.Path(f, { left: o, top: s, stroke: e.color, strokeWidth: u, fill: d }));
										break;
									case 'equilateral':
										(h = r.y - n.y),
											(l = new Et.Triangle({ top: n.y, left: n.x, width: Math.sqrt(Math.pow(h, 2) + Math.pow(h / 2, 2)), height: h, stroke: e.color, strokeWidth: u, fill: d }));
										break;
									case 'isosceles':
										(c = r.x - n.x), (h = r.y - n.y), (l = new Et.Triangle({ top: n.y, left: n.x, width: c, height: h, stroke: e.color, strokeWidth: u, fill: d }));
										break;
									case 'text':
										e.text
											? this.canvas.getObjects().forEach(t => {
													t.id === e.id && t.set('text', e.text);
											  })
											: ((this.textbox = new Et.Textbox('', { left: n.x - 60, top: n.y - 20, width: 150, fontSize: 30, borderColor: p, fill: e.color, hasControls: !1 })),
											  (this.textbox.id = e.id),
											  (this.textbox.remote = !0),
											  (this.textbox.selectable = !1),
											  this.canvas.add(this.textbox)),
											this.canvas.renderAll();
										break;
									case 'remove':
										{
											const t = this.canvas.getObjects();
											for (let i = t.length - 1; i >= 0; i--)
												if (t[i].id === e.id) {
													this.canvas.remove(t[i]);
													break;
												}
										}
										break;
									case 'pen':
										{
											const t = JSON.parse(e.object),
												i = this.canvas.getObjects();
											t.path.forEach(t => {
												f += t.join(' ') + ' ';
											});
											for (let n = i.length - 1; n >= 0; n--) if (i[n].id === e.id) return void i[n].set('path', f);
											l = new Et.Path(f, t);
										}
										break;
									case 'zoomout':
										console.warn('zoomout');
										break;
									case 'object:modified':
										{
											const { state: t } = e.value,
												i = this.canvas.getObjects(),
												n = i.filter(t => e.value.objects.includes(t.id)),
												r = new Et.ActiveSelection(n, { canvas: this.canvas });
											if (r) {
												var g = canvas.renderOnAddRemove;
												for (var v in ((canvas.renderOnAddRemove = !1), t)) r.set(v, t[v]);
												n.map(t => {
													(t.remote = !0), (t.selectable = !1);
												}),
													(canvas.renderOnAddRemove = g),
													canvas.renderAll();
											}
										}
										break;
									case 'object:added':
										if (e.value) {
											const t = JSON.parse(e.value);
											Et.util.enlivenObjects(t, t => {
												var i = canvas.renderOnAddRemove;
												(canvas.renderOnAddRemove = !1),
													(t[0].id = e.id),
													t.forEach(function (t) {
														(t.remote = !0), (t.selectable = !1), canvas.add(t);
													}),
													(canvas.renderOnAddRemove = i),
													canvas.renderAll();
											});
										}
										break;
									case 'object:removed':
										if (e.value) {
											const t = this.canvas.getObjects(),
												i = t.filter(t => e.value.includes(t.id));
											i.forEach(t => {
												this.canvas.remove(t);
											});
										}
										break;
									default:
										break;
								}
								l && ((l.id = e.id), (l.remote = !0), (l.selectable = !1), this.canvas.add(l));
							},
							notifyLoad() {
								this.notifyMsg({ method: 'load' });
							},
							zoomout() {
								var t = canvas.getZoom();
								(t -= 0.25), this.zoomToPoint(new Et.Point(this.canvas.width / 2, this.canvas.height / 2), t);
							},
							zoomin() {
								var t = canvas.getZoom();
								(t += 0.25), this.zoomToPoint(new Et.Point(this.canvas.width / 2, this.canvas.height / 2), t);
							},
							changSize() {
								const t = document.documentElement.clientWidth * this.zoom,
									e = document.documentElement.clientHeight * this.zoom;
								this.canvas.setHeight(e), this.canvas.setWidth(t);
							},
							undo() {
								tt.undo();
							},
							redo() {
								tt.redo();
							},
							enableSelector() {
								(this.canvas.selection = !0),
									(this.canvas.skipTargetFind = !1),
									(this.canvas.selectable = !0),
									this.canvas.forEachObject(function (t) {
										t.remote ? (t.selectable = !1) : (t.selectable = !0);
									});
							},
							disableSelector() {
								(this.canvas.selectable = !1),
									this.canvas.forEachObject(function (t) {
										t.selectable = !1;
									}),
									this.canvas.requestRenderAll(),
									(this.panning = !1);
							},
							setZoom(t) {
								t > g && (t = g), t < v && (t = v), this.canvas.setZoom(t), (this.zoom = t), P.setZoom(t);
							},
							zoomToPoint(t, e) {
								e > g && (e = g), e < v && (e = v), this.canvas.zoomToPoint(t, e), (this.zoom = e), P.setZoom(e);
							},
							initHistoryListen() {
								tt.on('object:modified', t => {
									this.$nextTick(() => {
										this.notifyUpdate({ drawType: 'object:modified', value: t });
									});
								}),
									tt.on('object:added', t => {
										this.$nextTick(() => {
											this.notifyUpdate({ drawType: 'object:added', id: t[0].id, value: JSON.stringify(t) });
										});
									}),
									tt.on('object:removed', t => {
										this.$nextTick(() => {
											this.notifyUpdate({ drawType: 'object:removed', value: t });
										});
									});
							}
						}
					},
					jt = Mt,
					Dt = (0, A.Z)(jt, kt, Pt, !1, null, '766903b9', null),
					At = Dt.exports,
					Ft = {
						name: 'App',
						components: { ToolBar: pt, WhiteBoard: At, ToolbarMobile: Ot },
						data() {
							return { isMobile: _, offsetTop: 0 };
						},
						mounted() {},
						beforeDestroy() {},
						methods: {
							viewportHandler() {
								const t = document.getElementById('app'),
									e = window.visualViewport.height - t.getBoundingClientRect().height + window.visualViewport.offsetTop;
								this.$nextTick(() => {
									this.offsetTop = e;
								});
							}
						}
					},
					Lt = Ft,
					It = (0, A.Z)(Lt, r, o, !1, null, '5a530814', null),
					Rt = It.exports;
				(n.ZP.config.productionTip = !1), new n.ZP({ render: t => t(Rt) }).$mount('#app');
			}
		},
		e = {};
	function i(n) {
		var r = e[n];
		if (void 0 !== r) return r.exports;
		var o = (e[n] = { exports: {} });
		return t[n](o, o.exports, i), o.exports;
	}
	(i.m = t),
		(function () {
			var t = [];
			i.O = function (e, n, r, o) {
				if (!n) {
					var s = 1 / 0;
					for (l = 0; l < t.length; l++) {
						(n = t[l][0]), (r = t[l][1]), (o = t[l][2]);
						for (var a = !0, c = 0; c < n.length; c++)
							(!1 & o || s >= o) &&
							Object.keys(i.O).every(function (t) {
								return i.O[t](n[c]);
							})
								? n.splice(c--, 1)
								: ((a = !1), o < s && (s = o));
						if (a) {
							t.splice(l--, 1);
							var h = r();
							void 0 !== h && (e = h);
						}
					}
					return e;
				}
				o = o || 0;
				for (var l = t.length; l > 0 && t[l - 1][2] > o; l--) t[l] = t[l - 1];
				t[l] = [n, r, o];
			};
		})(),
		(function () {
			i.d = function (t, e) {
				for (var n in e) i.o(e, n) && !i.o(t, n) && Object.defineProperty(t, n, { enumerable: !0, get: e[n] });
			};
		})(),
		(function () {
			i.g = (function () {
				if ('object' === typeof globalThis) return globalThis;
				try {
					return this || new Function('return this')();
				} catch (t) {
					if ('object' === typeof window) return window;
				}
			})();
		})(),
		(function () {
			i.o = function (t, e) {
				return Object.prototype.hasOwnProperty.call(t, e);
			};
		})(),
		(function () {
			var t = { 143: 0 };
			i.O.j = function (e) {
				return 0 === t[e];
			};
			var e = function (e, n) {
					var r,
						o,
						s = n[0],
						a = n[1],
						c = n[2],
						h = 0;
					if (
						s.some(function (e) {
							return 0 !== t[e];
						})
					) {
						for (r in a) i.o(a, r) && (i.m[r] = a[r]);
						if (c) var l = c(i);
					}
					for (e && e(n); h < s.length; h++) (o = s[h]), i.o(t, o) && t[o] && t[o][0](), (t[o] = 0);
					return i.O(l);
				},
				n = (self['webpackChunkcoshow_js_sdk_vue'] = self['webpackChunkcoshow_js_sdk_vue'] || []);
			n.forEach(e.bind(null, 0)), (n.push = e.bind(null, n.push.bind(n)));
		})();
	var n = i.O(void 0, [998], function () {
		return i(3028);
	});
	n = i.O(n);
})();
